diff --git a/.gitignore b/.gitignore index 228eee069009a..19e4afec5199b 100644 --- a/.gitignore +++ b/.gitignore @@ -109,8 +109,7 @@ Backup*/ UpgradeLog*.XML # NuGet -/microsoft-azure-api/Services/Storage/Test/Unit/RT/AppPackages/ -libraries/packages +packages # Mac development .DS_Store diff --git a/libraries/.nuget/NuGet.Config b/.nuget/NuGet.Config similarity index 100% rename from libraries/.nuget/NuGet.Config rename to .nuget/NuGet.Config diff --git a/libraries/.nuget/NuGet.exe b/.nuget/NuGet.exe similarity index 100% rename from libraries/.nuget/NuGet.exe rename to .nuget/NuGet.exe diff --git a/libraries/.nuget/NuGet.targets b/.nuget/NuGet.targets similarity index 100% rename from libraries/.nuget/NuGet.targets rename to .nuget/NuGet.targets diff --git a/README.md b/README.md index c67a76ce42133..fbd3882707803 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,9 @@ complete SDK, please see the [Windows Azure .NET Developer Center](http://www.wi # Features - Storage + + > Available in the separate [Storage repository](https://github.com/WindowsAzure/azure-storage-net/) + - Tables - Create/Delete Tables - Query/Create/Read/Update/Delete Entities @@ -18,6 +21,7 @@ complete SDK, please see the [Windows Azure .NET Developer Center](http://www.wi - Create/Delete Queues - Insert/Peek Queue Messages - Advanced Queue Operations + - Management Libraries (Preview) - Compute - Infrastructure @@ -68,61 +72,29 @@ We gladly accept community contributions. For general suggestions about Windows Azure please use our [UserVoice forum](http://www.mygreatwindowsazureidea.com/forums/34192-windows-azure-feature-voting). -# Storage Client Library for .NET 4, Windows 8, and Windows Phone 8 (2.1.0.0) +# Storage Client Library -The Storage Client Library ships with the Windows Azure SDK for .NET and also on NuGet. You'll find the latest version and hotfixes on NuGet via the `WindowsAzure.Storage` package. You can [read about the 2.1 release on the storage team blog post](http://blogs.msdn.com/b/windowsazurestorage/archive/2013/09/07/announcing-storage-client-library-2-1-rtm.aspx). +To use storage services (blog, table, queue), the storage client library provides rich APIs for interacting with the storage service. -Please note that Windows 8 and Windows Phone 8 libraries are CTP (Community -Technology Preview) releases. +The Storage Client Library ships with the Windows Azure SDK for .NET and also on NuGet. You'll find the latest version and hotfixes on NuGet via the `WindowsAzure.Storage` package. -## Download & Install - -### Via Git +## Storage source code -To get the source code of the SDK via git just type: +### v3.0+ -```bash -git clone git://github.com/WindowsAzure/azure-sdk-for-net.git -cd azure-sdk-for-net -``` +With the release of the 3.0.0 storage client library, you can find the latest storage library (and associated issues) in the separate repo [azure-storage-net](http://github.com/WindowsAzure/azure-storage-net/). -### Via NuGet +### v2.0.1.4 -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 .NET package manager [NuGet](http://www.nuget.org/). +The latest version of the v2.1.x storage client library is available in the azure-sdk-for-net repo under the [`v2.1.0.4` tag](https://github.com/WindowsAzure/azure-sdk-for-net/releases/tag/v2.1.0.4). -`Install-Package WindowsAzure.Storage` +## NuGet package install -## Dependencies +The storage client libaries are delivered via NuGet officially by Microsoft, ready for use within your project. They are installed with the [NuGet package manager](http://www.nuget.org/) which is built into Visual Studio 2013; for earlier releases of Visual Studio, NuGet is a quick and easy extension to install. -### OData - -This version depends on three libraries (collectively referred to as ODataLib), which are resolved through the ODataLib (version 5.2.0) packages available through NuGet and not the WCF Data Services installer which currently contains 5.0.0 versions. - -The ODataLib libraries can be downloaded directly or referenced by your code project through NuGet. - -The specific ODataLib packages are: - -- [Microsoft.Data.OData](http://nuget.org/packages/Microsoft.Data.OData/) -- [Microsoft.Data.Edm](http://nuget.org/packages/Microsoft.Data.Edm/) -- [System.Spatial](http://nuget.org/packages/System.Spatial) - -### Test Dependencies - -FiddlerCore is required by: - -- Test\Unit\FaultInjection\HttpMangler -- Test\Unit\FaultInjection\XStoreMangler -- Test\Unit\DotNet40 - -This dependency is not included and must be downloaded from [http://www.fiddler2.com/Fiddler/Core/](http://www.fiddler2.com/Fiddler/Core/). - -Once installed: - -- Copy `FiddlerCore.dll` `\azure-sdk-for-net\microsoft-azure-api\Services\Storage\Test\Unit\FaultInjection\Dependencies\DotNet2` -- Copy `FiddlerCore4.dll` to `azure-sdk-for-net\microsoft-azure-api\Services\Storage\Test\Unit\FaultInjection\Dependencies\DotNet4` +`Install-Package WindowsAzure.Storage` -## Code Samples +## Storage code samples > Note: > How-Tos focused around accomplishing specific tasks are available on the [Windows Azure .NET Developer Center](http://www.windowsazure.com/en-us/develop/net/). diff --git a/libraries/Settings.SourceAnalysis b/Settings.SourceAnalysis similarity index 100% rename from libraries/Settings.SourceAnalysis rename to Settings.SourceAnalysis diff --git a/libraries/WindowsAzureLibraries.sln b/WindowsAzureLibraries.sln similarity index 99% rename from libraries/WindowsAzureLibraries.sln rename to WindowsAzureLibraries.sln index 032c9eff379ea..67767d2c8ecc5 100644 --- a/libraries/WindowsAzureLibraries.sln +++ b/WindowsAzureLibraries.sln @@ -61,6 +61,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlManagement", "src\SqlManagement\SqlManagement.csproj", "{74CEEF0C-D9DB-412E-B6AD-F63020C0AC72}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StoreManagement", "src\StoreManagement\StoreManagement.csproj", "{E9119999-B156-4CE1-A83E-F7778992739B}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Tracing.Etw", "src\Common.Tracing.Etw\Common.Tracing.Etw.csproj", "{50B0A8CE-D290-4EB7-8C6C-16EAAB75225E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Tracing.Test", "src\Common.Tracing.Test\Common.Tracing.Test.csproj", "{B2FAA0E6-2643-4011-8CFE-BA28BDFFC7E7}" diff --git a/libraries/WindowsAzureLibraries.vsmdi b/WindowsAzureLibraries.vsmdi similarity index 100% rename from libraries/WindowsAzureLibraries.vsmdi rename to WindowsAzureLibraries.vsmdi diff --git a/libraries/libraries.msbuild b/libraries.msbuild similarity index 97% rename from libraries/libraries.msbuild rename to libraries.msbuild index dfb73344f53f3..5088e9091845d 100644 --- a/libraries/libraries.msbuild +++ b/libraries.msbuild @@ -65,9 +65,9 @@ - - - + + + - diff --git a/libraries/libraries.testsettings b/libraries.testsettings similarity index 100% rename from libraries/libraries.testsettings rename to libraries.testsettings diff --git a/microsoft-azure-api/Services/Storage/.gitattributes b/microsoft-azure-api/Services/Storage/.gitattributes deleted file mode 100644 index 1e11d3235cef3..0000000000000 --- a/microsoft-azure-api/Services/Storage/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -*.cs eol=crlf -*.csproj eol=crlf -*.sln eol=crlf diff --git a/microsoft-azure-api/Services/Storage/CustomDictionary.xml b/microsoft-azure-api/Services/Storage/CustomDictionary.xml deleted file mode 100644 index bfb660f6c5669..0000000000000 --- a/microsoft-azure-api/Services/Storage/CustomDictionary.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - Auth - api - sas - dest - Acl - Md - Eq - Canonicalizer - Async - orderby - IBufferManager - DynamicTableEntity - GetDefaultBufferSize - ITableEntity - EndRead - TableQuery - EndFlush - EntityProperty - ExecuteQuery - CloudTable - CreateQuery - TableQuery - EndFlush - EntityProperty - ExecuteQuery - CloudTable - CreateQuery - Etag - OData - - - Tablequery - Entityproperty - Executequery - Cloudtable - Createquery - Endflush - Beginflush - Endread - Numberless - - - etag - Etag - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/AccessCondition.cs b/microsoft-azure-api/Services/Storage/Lib/Common/AccessCondition.cs deleted file mode 100644 index 0ee742c1c5d46..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/AccessCondition.cs +++ /dev/null @@ -1,269 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a set of access conditions to be used for operations against the storage services. - /// - public sealed class AccessCondition - { - /// - /// Time for IfModifiedSince. - /// - private DateTimeOffset? ifModifiedSinceDateTime; - - /// - /// Time for IfUnmodifiedSince. - /// - private DateTimeOffset? ifNotModifiedSinceDateTime; - - /// - /// Gets or sets an ETag value that must match the ETag of the specified resource. - /// - /// A string containing an ETag value, or "*" to match any ETag. If null, no condition exists. - public string IfMatchETag - { - get; - set; - } - - /// - /// Gets or sets an ETag value that must not match the ETag of the specified resource. - /// - /// A string containing an ETag value, or "*" to match any ETag. If null, no condition exists. - public string IfNoneMatchETag - { - get; - set; - } - - /// - /// Gets or sets a time that must be before the last modification of a resource. - /// - /// A DateTimeOffset in UTC, or null if no condition exists. - public DateTimeOffset? IfModifiedSinceTime - { - get - { - return this.ifModifiedSinceDateTime; - } - - set - { - this.ifModifiedSinceDateTime = value.HasValue ? value.Value.ToUniversalTime() : value; - } - } - - /// - /// Gets or sets a time that must not be before the last modification of a resource. - /// - /// A DateTimeOffset in UTC, or null if no condition exists. - public DateTimeOffset? IfNotModifiedSinceTime - { - get - { - return this.ifNotModifiedSinceDateTime; - } - - set - { - this.ifNotModifiedSinceDateTime = value.HasValue ? value.Value.ToUniversalTime() : value; - } - } - - /// - /// Gets or sets a sequence number that the current sequence number of a page blob must be less than or equal to in order for the operation to proceed. - /// - /// A sequence number, or null if no condition exists. - /// This condition only applies to page blobs. - public long? IfSequenceNumberLessThanOrEqual - { - get; - set; - } - - /// - /// Gets or sets a sequence number that the current sequence number of a page blob must be less than in order for the operation to proceed. - /// - /// A sequence number, or null if no condition exists. - /// This condition only applies to page blobs. - public long? IfSequenceNumberLessThan - { - get; - set; - } - - /// - /// Gets or sets a sequence number that the current sequence number of a page blob must be equal to in order for the operation to proceed. - /// - /// A sequence number, or null if no condition exists. - /// This condition only applies to page blobs. - public long? IfSequenceNumberEqual - { - get; - set; - } - - /// - /// Gets or sets a lease ID that must match the lease on a resource. - /// - /// A lease ID, or null if no condition exists. - public string LeaseId - { - get; - set; - } - - /// - /// Determines whether the access condition is one of the four conditional headers. - /// - /// true if the access condition is a conditional header; otherwise, false. - internal bool IsConditional - { - get - { - return !string.IsNullOrEmpty(this.IfMatchETag) || - !string.IsNullOrEmpty(this.IfNoneMatchETag) || - this.IfModifiedSinceTime.HasValue || - this.IfNotModifiedSinceTime.HasValue; - } - } - - /// - /// Constructs an empty access condition. - /// - /// An empty access condition. - public static AccessCondition GenerateEmptyCondition() - { - return new AccessCondition(); - } - - /// - /// Constructs an access condition such that an operation will be performed only if the resource's ETag value - /// matches the specified ETag value. - /// - /// The ETag value that must be matched. - /// An AccessCondition object that represents the If-Match condition. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "etag", Justification = "Reviewed: etag can be used for identifier names.")] - public static AccessCondition GenerateIfMatchCondition(string etag) - { - return new AccessCondition { IfMatchETag = etag }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if the resource has been - /// modified since the specified time. - /// - /// The time since which the resource must have been modified in order for the operation to proceed. - /// An AccessCondition object that represents the If-Modified-Since condition. - public static AccessCondition GenerateIfModifiedSinceCondition(DateTimeOffset modifiedTime) - { - return new AccessCondition { IfModifiedSinceTime = modifiedTime }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if the resource's ETag value - /// does not match the specified ETag value. - /// - /// The ETag value that must be matched, or "*". - /// An AccessCondition object that represents the If-None-Match condition. - /// - /// If "*" is specified as the parameter then this condition requires that the resource does not exist. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "etag", Justification = "Reviewed: etag can be used for identifier names.")] - public static AccessCondition GenerateIfNoneMatchCondition(string etag) - { - return new AccessCondition { IfNoneMatchETag = etag }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if the resource has not been - /// modified since the specified time. - /// - /// The time since which the resource must not have been modified in order for the operation to proceed. - /// An AccessCondition object that represents the If-Unmodified-Since condition. - public static AccessCondition GenerateIfNotModifiedSinceCondition(DateTimeOffset modifiedTime) - { - return new AccessCondition { IfNotModifiedSinceTime = modifiedTime }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if resource's current sequence - /// number is less than or equal to the specified value. - /// - /// The value that the current sequence number of the resource must be less than or equal to. - /// An AccessCondition object that represents the If-Sequence-Number-LE condition. - public static AccessCondition GenerateIfSequenceNumberLessThanOrEqualCondition(long sequenceNumber) - { - return new AccessCondition { IfSequenceNumberLessThanOrEqual = sequenceNumber }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if resource's current sequence - /// number is less than the specified value. - /// - /// The value that the current sequence number of the resource must be less than. - /// An AccessCondition object that represents the If-Sequence-Number-LT condition. - public static AccessCondition GenerateIfSequenceNumberLessThanCondition(long sequenceNumber) - { - return new AccessCondition { IfSequenceNumberLessThan = sequenceNumber }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if resource's current sequence - /// number is equal to the specified value. - /// - /// The value that the current sequence number of the resource must be equal to. - /// An AccessCondition object that represents the If-Sequence-Number-EQ condition. - public static AccessCondition GenerateIfSequenceNumberEqualCondition(long sequenceNumber) - { - return new AccessCondition { IfSequenceNumberEqual = sequenceNumber }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if the lease ID on the - /// resource matches the specified lease ID. - /// - /// The lease ID that must match the lease ID of the resource. - /// An AccessCondition object that represents the lease condition. - public static AccessCondition GenerateLeaseCondition(string leaseId) - { - return new AccessCondition { LeaseId = leaseId }; - } - - /// - /// Constructs an access condition such that an operation will be performed only if the resource's ETag value - /// matches the specified ETag value and the lease ID on the resource matches the lease ID specified in - /// the given access condition. - /// - /// An AccessCondition object that represents the lease condition. - /// The ETag value that must be matched. - /// An AccessCondition object that represents the If-Match and the lease conditions. - internal static AccessCondition CloneConditionWithETag(AccessCondition accessCondition, string etag) - { - return new AccessCondition - { - IfMatchETag = etag, - LeaseId = accessCondition != null ? accessCondition.LeaseId : null, - }; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageAccountKey.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageAccountKey.cs deleted file mode 100644 index a300392ab8672..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageAccountKey.cs +++ /dev/null @@ -1,31 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth -{ - internal struct StorageAccountKey - { - internal string KeyName; - internal byte[] KeyValue; - - public StorageAccountKey(string keyName, byte[] keyValue) - { - this.KeyName = keyName; - this.KeyValue = keyValue; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageCredentials.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageCredentials.cs deleted file mode 100644 index a79314f6029e1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Auth/StorageCredentials.cs +++ /dev/null @@ -1,351 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Represents a set of credentials used to authenticate access to a Windows Azure storage account. - /// - public sealed class StorageCredentials - { - private UriQueryBuilder queryBuilder; - - /// - /// Gets the associated shared access signature token for the credentials. - /// - /// The shared access signature token. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SAS", Justification = "Back compatibility.")] - public string SASToken { get; private set; } - - /// - /// Gets the associated account name for the credentials. - /// - /// The account name. - public string AccountName { get; private set; } - - /// - /// Gets the associated key name for the credentials. - /// - /// The key name. - public string KeyName - { - get - { - return this.Key.KeyName; - } - } - - internal StorageAccountKey Key { get; private set; } - - /// - /// Gets a value indicating whether the credentials are for anonymous access. - /// - /// true if the credentials are for anonymous access; otherwise, false. - public bool IsAnonymous - { - get - { - return (this.SASToken == null) && (this.AccountName == null); - } - } - - /// - /// Gets a value indicating whether the credentials are a shared access signature token. - /// - /// true if the credentials are a shared access signature token; otherwise, false. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SAS", Justification = "Back compatibility.")] - public bool IsSAS - { - get - { - return (this.SASToken != null) && (this.AccountName == null); - } - } - - /// - /// Gets a value indicating whether the credentials are a shared key. - /// - /// true if the credentials are a shared key; otherwise, false. - public bool IsSharedKey - { - get - { - return (this.SASToken == null) && (this.AccountName != null); - } - } - - /// - /// Initializes a new instance of the class. - /// - public StorageCredentials() - { - } - - /// - /// Initializes a new instance of the class with the specified account name and key value. - /// - /// A string that represents the name of the storage account. - /// A string that represents the Base64-encoded account access key. - public StorageCredentials(string accountName, string keyValue) - : this(accountName, keyValue, null) - { - } - -#if WINDOWS_DESKTOP - /// - /// Initializes a new instance of the class with the specified account name and key value. - /// - /// A string that represents the name of the storage account. - /// An array of bytes that represent the account access key. - public StorageCredentials(string accountName, byte[] keyValue) - : this(accountName, keyValue, null) - { - } -#endif - - /// - /// Initializes a new instance of the class with the specified account name, key value, and key name. - /// - /// A string that represents the name of the storage account. - /// A string that represents the Base64-encoded account access key. - /// A string that represents the name of the key. - public StorageCredentials(string accountName, string keyValue, string keyName) - { - if (string.IsNullOrEmpty(accountName)) - { - throw new ArgumentNullException("accountName"); - } - - this.AccountName = accountName; - this.UpdateKey(keyValue, keyName); - } - -#if WINDOWS_DESKTOP - /// - /// Initializes a new instance of the class with the specified account name, key value, and key name. - /// - /// A string that represents the name of the storage account. - /// An array of bytes that represent the account access key. - /// A string that represents the name of the key. - public StorageCredentials(string accountName, byte[] keyValue, string keyName) - { - if (string.IsNullOrEmpty(accountName)) - { - throw new ArgumentNullException("accountName"); - } - - this.AccountName = accountName; - this.UpdateKey(keyValue, keyName); - } -#endif - - /// - /// Initializes a new instance of the class with the specified shared access signature token. - /// - /// A string representing the shared access signature token. - public StorageCredentials(string sasToken) - { - if (string.IsNullOrEmpty(sasToken)) - { - throw new ArgumentNullException("sasToken"); - } - - this.SASToken = sasToken; - this.UpdateQueryBuilder(); - } - - /// - /// Updates the key value for the credentials. - /// - /// The key value, as a Base64-encoded string, to update. - public void UpdateKey(string keyValue) - { - this.UpdateKey(keyValue, null); - } - -#if WINDOWS_DESKTOP - /// - /// Updates the key value for the credentials. - /// - /// The key value, as an array of bytes, to update. - public void UpdateKey(byte[] keyValue) - { - this.UpdateKey(keyValue, null); - } -#endif - - /// - /// Updates the key value and key name for the credentials. - /// - /// The key value, as a Base64-encoded string, to update. - /// The key name to update. - public void UpdateKey(string keyValue, string keyName) - { - if (!this.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotUpdateKeyWithoutAccountKeyCreds); - throw new InvalidOperationException(errorMessage); - } - - if (keyValue == null) - { - throw new ArgumentNullException("keyValue"); - } - - this.Key = new StorageAccountKey(keyName, Convert.FromBase64String(keyValue)); - } - -#if WINDOWS_DESKTOP - /// - /// Updates the key value and key name for the credentials. - /// - /// The key value, as an array of bytes, to update. - /// The key name to update. - public void UpdateKey(byte[] keyValue, string keyName) - { - if (!this.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotUpdateKeyWithoutAccountKeyCreds); - throw new InvalidOperationException(errorMessage); - } - - if (keyValue == null) - { - throw new ArgumentNullException("keyValue"); - } - - this.Key = new StorageAccountKey(keyName, keyValue); - } -#endif - - /// - /// Updates the shared access signature (SAS) token value for storage credentials created with a shared access signature. - /// - /// A string that specifies the SAS token value to update. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SAS", Justification = "Back compatibility.")] - public void UpdateSASToken(string sasToken) - { - if (!this.IsSAS) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotUpdateSasWithoutSasCreds); - throw new InvalidOperationException(errorMessage); - } - - if (string.IsNullOrEmpty(sasToken)) - { - throw new ArgumentNullException("sasToken"); - } - - this.SASToken = sasToken; - this.UpdateQueryBuilder(); - } - - /// - /// Returns the account key for the credentials. - /// - /// An array of bytes that contains the key. - public byte[] ExportKey() - { - return (byte[])this.Key.KeyValue.Clone(); - } - - /// - /// Transforms a resource URI into a shared access signature URI, by appending a shared access token. - /// - /// A object that represents the resource URI to be transformed. - /// A object that represents the signature, including the resource URI and the shared access token. - public Uri TransformUri(Uri resourceUri) - { - if (this.IsSAS) - { - return this.queryBuilder.AddToUri(resourceUri); - } - else - { - return resourceUri; - } - } - - /// - /// Exports the value of the account access key to a Base64-encoded string. - /// - /// The account access key. - public string ExportBase64EncodedKey() - { - StorageAccountKey localKey = this.Key; - return (localKey.KeyValue == null) ? null : Convert.ToBase64String(localKey.KeyValue); - } - - internal string ToString(bool exportSecrets) - { - if (this.IsSharedKey) - { - return string.Format( - CultureInfo.InvariantCulture, - "{0}={1};{2}={3}", - CloudStorageAccount.AccountNameSettingString, - this.AccountName, - CloudStorageAccount.AccountKeySettingString, - exportSecrets ? this.ExportBase64EncodedKey() : "[key hidden]"); - } - - if (this.IsSAS) - { - return string.Format(CultureInfo.InvariantCulture, "{0}={1}", CloudStorageAccount.SharedAccessSignatureSettingString, exportSecrets ? this.SASToken : "[signature hidden]"); - } - - return string.Empty; - } - - /// - /// Determines whether an other object is equal to this one by comparing their SAS tokens, account names, key names, and key values. - /// - /// The object to compare to this one. - /// true if the two objects are equal; otherwise, false. - public bool Equals(StorageCredentials other) - { - if (other == null) - { - return false; - } - else - { - return string.Equals(this.SASToken, other.SASToken) && - string.Equals(this.AccountName, other.AccountName) && - string.Equals(this.KeyName, other.KeyName) && - string.Equals(this.ExportBase64EncodedKey(), other.ExportBase64EncodedKey()); - } - } - - private void UpdateQueryBuilder() - { - this.queryBuilder = new UriQueryBuilder(); - IDictionary parameters = HttpWebUtility.ParseQueryString(this.SASToken); - foreach (KeyValuePair parameter in parameters) - { - this.queryBuilder.Add(parameter.Key, parameter.Value); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/AuthenticationScheme.cs b/microsoft-azure-api/Services/Storage/Lib/Common/AuthenticationScheme.cs deleted file mode 100644 index b0986d838d8e0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/AuthenticationScheme.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - /// - /// Specifies the authentication scheme used to sign HTTP requests. - /// - public enum AuthenticationScheme - { - /// - /// Signs HTTP requests using the Shared Key Lite authentication scheme. - /// - SharedKeyLite, - - /// - /// Signs HTTP requests using the Shared Key authentication scheme. - /// - SharedKey - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobAttributes.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobAttributes.cs deleted file mode 100644 index 93826ba0bd62a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobAttributes.cs +++ /dev/null @@ -1,78 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Globalization; - - internal sealed class BlobAttributes - { - internal BlobAttributes() - { - this.Properties = new BlobProperties(); - this.Metadata = new Dictionary(); - } - - /// - /// Gets the blob's system properties. - /// - /// The blob's properties. - public BlobProperties Properties { get; internal set; } - - /// - /// Gets the user-defined metadata for the blob. - /// - /// The blob's metadata, as a collection of name-value pairs. - public IDictionary Metadata { get; internal set; } - - /// - /// Gets the blob's URI. - /// - /// The absolute URI to the blob. - public Uri Uri { get; internal set; } - - /// - /// Gets the date and time that the blob snapshot was taken, if this blob is a snapshot. - /// - /// The blob's snapshot time if the blob is a snapshot; otherwise, null. - /// - /// If the blob is not a snapshot, the value of this property is null. - /// - public DateTimeOffset? SnapshotTime { get; internal set; } - - /// - /// Gets the state of the most recent or pending copy operation. - /// - /// A object containing the copy state, or null if no copy blob state exists for this blob. - public CopyState CopyState { get; internal set; } - - /// - /// Verifies that the blob is not a snapshot. - /// - internal void AssertNoSnapshot() - { - if (this.SnapshotTime.HasValue) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotModifySnapshot); - throw new InvalidOperationException(errorMessage); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPermissions.cs deleted file mode 100644 index 6aeb65d847e37..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPermissions.cs +++ /dev/null @@ -1,46 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Represents the permissions for a container. - /// - public sealed class BlobContainerPermissions - { - /// - /// Initializes a new instance of the class. - /// - public BlobContainerPermissions() - { - this.PublicAccess = BlobContainerPublicAccessType.Off; - this.SharedAccessPolicies = new SharedAccessBlobPolicies(); - } - - /// - /// Gets or sets the public access setting for the container. - /// - /// The public access setting for the container. - public BlobContainerPublicAccessType PublicAccess { get; set; } - - /// - /// Gets the set of shared access policies for the container. - /// - /// The set of shared access policies for the container. - public SharedAccessBlobPolicies SharedAccessPolicies { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerProperties.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerProperties.cs deleted file mode 100644 index d4f9d35c64e3b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerProperties.cs +++ /dev/null @@ -1,57 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Represents the system properties for a container. - /// - public sealed class BlobContainerProperties - { - /// - /// Gets the ETag value for the container. - /// - /// The container's quoted ETag value. - public string ETag { get; internal set; } - - /// - /// Gets the container's last-modified time. - /// - /// The container's last-modified time. - public DateTimeOffset? LastModified { get; internal set; } - - /// - /// Gets the container's lease status. - /// - /// A object that indicates the container's lease status. - public LeaseStatus LeaseStatus { get; internal set; } - - /// - /// Gets the container's lease state. - /// - /// A object that indicates the container's lease state. - public LeaseState LeaseState { get; internal set; } - - /// - /// Gets the container's lease duration. - /// - /// A object that indicates the container's lease duration. - public LeaseDuration LeaseDuration { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPublicAccessType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPublicAccessType.cs deleted file mode 100644 index 86b5053a8886b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContainerPublicAccessType.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Specifies the level of public access that is allowed on the container. - /// - public enum BlobContainerPublicAccessType - { - /// - /// No public access. Only the account owner can read resources in this container. - /// - Off, - - /// - /// Container-level public access. Anonymous clients can read container and blob data. - /// - Container, - - /// - /// Blob-level public access. Anonymous clients can read blob data within this container, but not container data. - /// - Blob - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContinuationToken.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContinuationToken.cs deleted file mode 100644 index 9f3646234e430..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobContinuationToken.cs +++ /dev/null @@ -1,140 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Xml; - using System.Xml.Schema; - using System.Xml.Serialization; - - /// - /// Represents a continuation token for listing operations. - /// - /// continuation tokens are used in methods that return a object, such as . - [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1001:CommasMustBeSpacedCorrectly", Justification = "Reviewed.")] - public sealed class BlobContinuationToken : IContinuationToken -#if WINDOWS_DESKTOP - , IXmlSerializable -#endif - { - /// - /// Gets or sets the next marker for continuing results for enumeration operations. - /// - /// The next marker. - public string NextMarker { get; set; } - -#if WINDOWS_DESKTOP - /// - /// Gets an XML representation of an object. - /// - /// - /// An that describes the XML representation of the object that is produced by the method and consumed by the method. - /// - public XmlSchema GetSchema() - { - return null; - } - - /// - /// Generates a serializable continuation token from its XML representation. - /// - /// The stream from which the continuation token is deserialized. - public void ReadXml(XmlReader reader) - { - CommonUtility.AssertNotNull("reader", reader); - - reader.MoveToContent(); - - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - reader.ReadStartElement(); - while (reader.IsStartElement()) - { - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.ContinuationConstants.VersionElement: - string version = reader.ReadElementContentAsString(); - if (version != Constants.ContinuationConstants.CurrentVersion) - { - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, version)); - } - - break; - - case Constants.ContinuationConstants.NextMarkerElement: - this.NextMarker = reader.ReadElementContentAsString(); - break; - - case Constants.ContinuationConstants.TypeElement: - string continuationType = reader.ReadElementContentAsString(); - if (Constants.ContinuationConstants.BlobType != continuationType) - { - throw new XmlException(SR.UnexpectedContinuationType); - } - - break; - - default: - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, reader.Name)); - } - } - } - - reader.ReadEndElement(); - } - } - - /// - /// Converts a serializable continuation token into its XML representation. - /// - /// The stream to which the continuation token is serialized. - public void WriteXml(XmlWriter writer) - { - CommonUtility.AssertNotNull("writer", writer); - - writer.WriteStartElement(Constants.ContinuationConstants.ContinuationTopElement); - - writer.WriteElementString(Constants.ContinuationConstants.VersionElement, Constants.ContinuationConstants.CurrentVersion); - - writer.WriteElementString(Constants.ContinuationConstants.TypeElement, Constants.ContinuationConstants.BlobType); - - if (this.NextMarker != null) - { - writer.WriteElementString(Constants.ContinuationConstants.NextMarkerElement, this.NextMarker); - } - - writer.WriteEndElement(); // End ContinuationToken - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobListingDetails.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobListingDetails.cs deleted file mode 100644 index 59f53965a241f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobListingDetails.cs +++ /dev/null @@ -1,58 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Specifies which items to include when listing a set of blobs. - /// - [Flags] - public enum BlobListingDetails - { - /// - /// List only committed blobs, and do not return blob metadata. - /// - None = 0x0, - - /// - /// List committed blobs and blob snapshots. - /// - Snapshots = 0x1, - - /// - /// Retrieve blob metadata for each blob returned in the listing. - /// - Metadata = 0x2, - - /// - /// List committed and uncommitted blobs. - /// - UncommittedBlobs = 0x4, - - /// - /// Include copy properties in the listing. - /// - Copy = 0x8, - - /// - /// List all available committed blobs, uncommitted blobs, and snapshots, and return all metadata and copy status for those blobs. - /// - All = 0xF - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobProperties.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobProperties.cs deleted file mode 100644 index bdcf3d9330cf0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobProperties.cs +++ /dev/null @@ -1,144 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - - /// - /// Represents the system properties for a blob. - /// - public sealed class BlobProperties - { - /// - /// Initializes a new instance of the class. - /// - public BlobProperties() - { - this.Length = -1; - } - - /// - /// Initializes a new instance of the class based on an existing instance. - /// - /// The set of properties to clone. - /// Lease-related properties will not be cloned, because a lease associated with the base blob is not copied to the snapshot. - public BlobProperties(BlobProperties other) - { - CommonUtility.AssertNotNull("other", other); - - this.BlobType = other.BlobType; - this.ContentType = other.ContentType; - this.ContentEncoding = other.ContentEncoding; - this.ContentLanguage = other.ContentLanguage; - this.CacheControl = other.CacheControl; - this.ContentMD5 = other.ContentMD5; - this.Length = other.Length; - this.ETag = other.ETag; - this.LastModified = other.LastModified; - this.PageBlobSequenceNumber = other.PageBlobSequenceNumber; - } - - /// - /// Gets or sets the cache-control value stored for the blob. - /// - /// The blob's cache-control value. - public string CacheControl { get; set; } - - /// - /// Gets or sets the content-encoding value stored for the blob. - /// - /// The blob's content-encoding value. - /// - /// If this property has not been set for the blob, it returns null. - /// - public string ContentEncoding { get; set; } - - /// - /// Gets or sets the content-language value stored for the blob. - /// - /// The blob's content-language value. - /// - /// If this property has not been set for the blob, it returns null. - /// - public string ContentLanguage { get; set; } - - /// - /// Gets the size of the blob, in bytes. - /// - /// The blob's size in bytes. - public long Length { get; internal set; } - - /// - /// Gets or sets the content-MD5 value stored for the blob. - /// - /// The blob's content-MD5 hash. - public string ContentMD5 { get; set; } - - /// - /// Gets or sets the content-type value stored for the blob. - /// - /// The blob's content-type value. - /// - /// If this property has not been set for the blob, it returns null. - /// - public string ContentType { get; set; } - - /// - /// Gets the blob's ETag value. - /// - /// The blob's ETag value. - public string ETag { get; internal set; } - - /// - /// Gets the the last-modified time for the blob, expressed as a UTC value. - /// - /// The blob's last-modified time, in UTC format. - public DateTimeOffset? LastModified { get; internal set; } - - /// - /// Gets the type of the blob. - /// - /// A object that indicates the type of the blob. - public BlobType BlobType { get; internal set; } - - /// - /// Gets the blob's lease status. - /// - /// A object that indicates the blob's lease status. - public LeaseStatus LeaseStatus { get; internal set; } - - /// - /// Gets the blob's lease state. - /// - /// A object that indicates the blob's lease state. - public LeaseState LeaseState { get; internal set; } - - /// - /// Gets the blob's lease duration. - /// - /// A object that indicates the blob's lease duration. - public LeaseDuration LeaseDuration { get; internal set; } - - /// - /// If the blob is a page blob, gets the blob's current sequence number. - /// - /// The blob's current sequence number. - public long? PageBlobSequenceNumber { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobReadStreamBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobReadStreamBase.cs deleted file mode 100644 index 23bbab9f826d9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobReadStreamBase.cs +++ /dev/null @@ -1,299 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - internal abstract class BlobReadStreamBase : Stream - { - protected ICloudBlob blob; - protected BlobProperties blobProperties; - protected long currentOffset; - protected MemoryStream internalBuffer; - protected int streamMinimumReadSizeInBytes; - protected AccessCondition accessCondition; - protected BlobRequestOptions options; - protected OperationContext operationContext; - protected MD5Wrapper blobMD5; - protected volatile Exception lastException; - - /// - /// Initializes a new instance of the BlobReadStreamBase class. - /// - /// Blob reference to read from - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - protected BlobReadStreamBase(ICloudBlob blob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - if (options.UseTransactionalMD5.Value) - { - CommonUtility.AssertInBounds("StreamMinimumReadSizeInBytes", blob.StreamMinimumReadSizeInBytes, 1, Constants.MaxRangeGetContentMD5Size); - } - - this.blob = blob; - this.blobProperties = new BlobProperties(blob.Properties); - this.currentOffset = 0; - this.streamMinimumReadSizeInBytes = this.blob.StreamMinimumReadSizeInBytes; - this.internalBuffer = new MemoryStream(this.streamMinimumReadSizeInBytes); - this.accessCondition = accessCondition; - this.options = options; - this.operationContext = operationContext; - this.blobMD5 = (this.options.DisableContentMD5Validation.Value || string.IsNullOrEmpty(this.blobProperties.ContentMD5)) ? null : new MD5Wrapper(); - this.lastException = null; - } - - /// - /// Gets a value indicating whether the current stream supports reading. - /// - public override bool CanRead - { - get - { - return true; - } - } - - /// - /// Gets a value indicating whether the current stream supports seeking. - /// - public override bool CanSeek - { - get - { - return true; - } - } - - /// - /// Gets a value indicating whether the current stream supports writing. - /// - public override bool CanWrite - { - get - { - return false; - } - } - - /// - /// Gets or sets the position within the current stream. - /// - public override long Position - { - get - { - return this.currentOffset; - } - - set - { - this.Seek(value, SeekOrigin.Begin); - } - } - - /// - /// Gets the length in bytes of the stream. - /// - /// The length in bytes of the stream. - public override long Length - { - get - { - return this.blobProperties.Length; - } - } - - /// - /// Sets the position within the current stream. - /// - /// A byte offset relative to the origin parameter. - /// A value of type SeekOrigin indicating the reference - /// point used to obtain the new position. - /// The new position within the current stream. - /// Seeking in a BlobReadStream disables MD5 validation. - public override long Seek(long offset, SeekOrigin origin) - { - if (this.lastException != null) - { - throw this.lastException; - } - - long newOffset; - switch (origin) - { - case SeekOrigin.Begin: - newOffset = offset; - break; - - case SeekOrigin.Current: - newOffset = this.currentOffset + offset; - break; - - case SeekOrigin.End: - newOffset = this.Length + offset; - break; - - default: - CommonUtility.ArgumentOutOfRange("origin", origin); - throw new ArgumentOutOfRangeException("origin"); - } - - CommonUtility.AssertInBounds("offset", newOffset, 0, this.Length); - - if (newOffset != this.currentOffset) - { - long bufferOffset = this.internalBuffer.Position + (newOffset - this.currentOffset); - if ((bufferOffset >= 0) && (bufferOffset < this.internalBuffer.Length)) - { - this.internalBuffer.Position = bufferOffset; - } - else - { - this.internalBuffer.SetLength(0); - } - - this.blobMD5 = null; - this.currentOffset = newOffset; - } - - return this.currentOffset; - } - - /// - /// This operation is not supported in BlobReadStreamBase. - /// - /// Not used. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// This operation is not supported in BlobReadStreamBase. - /// - /// Not used. - /// Not used. - /// Not used. - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - /// - /// This operation is a no-op in BlobReadStreamBase. - /// - public override void Flush() - { - } - - /// - /// Read as much as we can from the internal buffer - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// Number of bytes read from the stream. - protected int ConsumeBuffer(byte[] buffer, int offset, int count) - { - int readCount = this.internalBuffer.Read(buffer, offset, count); - this.currentOffset += readCount; - this.VerifyBlobMD5(buffer, offset, readCount); - return readCount; - } - - /// - /// Calculates the number of bytes to read from the blob. - /// - /// Number of bytes to read. - protected int GetReadSize() - { - if (this.currentOffset < this.Length) - { - return (int)Math.Min(this.streamMinimumReadSizeInBytes, this.Length - this.currentOffset); - } - else - { - return 0; - } - } - - /// - /// Updates the blob MD5 with newly downloaded content. - /// - /// The buffer to read the data from. - /// The byte offset in buffer at which to begin reading data. - /// The maximum number of bytes to read. - protected void VerifyBlobMD5(byte[] buffer, int offset, int count) - { - if ((this.blobMD5 != null) && (this.lastException == null) && (count > 0)) - { - this.blobMD5.UpdateHash(buffer, offset, count); - - if ((this.currentOffset == this.Length) && - !string.IsNullOrEmpty(this.blobProperties.ContentMD5)) - { - string computedMD5 = this.blobMD5.ComputeHash(); - this.blobMD5.Dispose(); - this.blobMD5 = null; - - if (!computedMD5.Equals(this.blobProperties.ContentMD5)) - { - this.lastException = new IOException(string.Format( - CultureInfo.InvariantCulture, - SR.BlobDataCorrupted, - this.blobProperties.ContentMD5, - computedMD5)); - } - } - } - } - - /// - /// Releases the blob resources used by the Stream. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (this.blobMD5 != null) - { - this.blobMD5.Dispose(); - this.blobMD5 = null; - } - - if (this.internalBuffer != null) - { - this.internalBuffer.Dispose(); - this.internalBuffer = null; - } - } - - base.Dispose(disposing); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobRequestOptions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobRequestOptions.cs deleted file mode 100644 index 283e27810fe2a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobRequestOptions.cs +++ /dev/null @@ -1,189 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using System; - - /// - /// Represents a set of timeout and retry policy options that may be specified for a request against the Blob service. - /// - public sealed class BlobRequestOptions : IRequestOptions - { - /// - /// Initializes a new instance of the class. - /// - public BlobRequestOptions() - { - } - - /// - /// Clones an instance of BlobRequestOptions so that we can apply defaults. - /// - /// BlobRequestOptions instance to be cloned. - internal BlobRequestOptions(BlobRequestOptions other) - : this() - { - if (other != null) - { - this.RetryPolicy = other.RetryPolicy; - this.ServerTimeout = other.ServerTimeout; - this.MaximumExecutionTime = other.MaximumExecutionTime; - this.OperationExpiryTime = other.OperationExpiryTime; - this.UseTransactionalMD5 = other.UseTransactionalMD5; - this.StoreBlobContentMD5 = other.StoreBlobContentMD5; - this.DisableContentMD5Validation = other.DisableContentMD5Validation; - } - } - - internal static BlobRequestOptions ApplyDefaults(BlobRequestOptions options, BlobType blobType, CloudBlobClient serviceClient, bool applyExpiry = true) - { - BlobRequestOptions modifiedOptions = new BlobRequestOptions(options); - - modifiedOptions.RetryPolicy = modifiedOptions.RetryPolicy ?? serviceClient.RetryPolicy; - modifiedOptions.ServerTimeout = modifiedOptions.ServerTimeout ?? serviceClient.ServerTimeout; - modifiedOptions.MaximumExecutionTime = modifiedOptions.MaximumExecutionTime ?? serviceClient.MaximumExecutionTime; - - if (applyExpiry && !modifiedOptions.OperationExpiryTime.HasValue && modifiedOptions.MaximumExecutionTime.HasValue) - { - modifiedOptions.OperationExpiryTime = DateTime.Now + modifiedOptions.MaximumExecutionTime.Value; - } - -#if WINDOWS_PHONE - modifiedOptions.DisableContentMD5Validation = true; - modifiedOptions.StoreBlobContentMD5 = false; - modifiedOptions.UseTransactionalMD5 = false; -#else - modifiedOptions.DisableContentMD5Validation = modifiedOptions.DisableContentMD5Validation ?? false; - modifiedOptions.StoreBlobContentMD5 = modifiedOptions.StoreBlobContentMD5 ?? (blobType == BlobType.BlockBlob); - modifiedOptions.UseTransactionalMD5 = modifiedOptions.UseTransactionalMD5 ?? false; -#endif - - return modifiedOptions; - } - - /// - /// Gets or sets the absolute expiry time across all potential retries for the request. - /// - internal DateTime? OperationExpiryTime { get; set; } - - /// - /// Gets or sets the retry policy. - /// - /// The retry policy. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the server timeout interval for the request. - /// - /// The server timeout interval for the request. - public TimeSpan? ServerTimeout { get; set; } - - /// - /// Gets or sets the maximum execution time across all potential retries for the request. - /// - /// A representing the maximum execution time for retries for the request. - public TimeSpan? MaximumExecutionTime { get; set; } - - /// - /// Gets or sets a value to calculate and send/validate content MD5 for transactions. - /// - /// Use true to calculate and send/validate content MD5 for transactions; otherwise, false. -#if WINDOWS_PHONE - /// This property is not supported for Windows Phone. -#endif - public bool? UseTransactionalMD5 - { - get - { - return this.useTransactionalMD5; - } - - set - { -#if WINDOWS_PHONE - if (value.HasValue && value.Value) - { - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); - } -#endif - this.useTransactionalMD5 = value; - } - } - - private bool? useTransactionalMD5; - - /// - /// Gets or sets a value to indicate that an MD5 hash will be calculated and stored when uploading a blob. - /// - /// Use true to calculate and store an MD5 hash when uploading a blob; otherwise, false. -#if WINDOWS_PHONE - /// This property is not supported for Windows Phone. -#endif - public bool? StoreBlobContentMD5 - { - get - { - return this.storeBlobContentMD5; - } - - set - { -#if WINDOWS_PHONE - if (value.HasValue && value.Value) - { - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); - } -#endif - this.storeBlobContentMD5 = value; - } - } - - private bool? storeBlobContentMD5; - - /// - /// Gets or sets a value to indicate that MD5 validation will be disabled when downloading blobs. - /// - /// Use true to disable MD5 validation; false to enable MD5 validation. -#if WINDOWS_PHONE - /// This property is not supported for Windows Phone. -#endif - public bool? DisableContentMD5Validation - { - get - { - return this.disableContentMD5Validation; - } - - set - { -#if WINDOWS_PHONE - if (value.HasValue && !value.Value) - { - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); - } -#endif - this.disableContentMD5Validation = value; - } - } - - private bool? disableContentMD5Validation; - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobResultSegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobResultSegment.cs deleted file mode 100644 index 4b53c179c9eed..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobResultSegment.cs +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System.Collections.Generic; - - /// - /// Represents a segment of results, with continuation information for pagination scenarios. - /// - public sealed class BlobResultSegment - { - internal BlobResultSegment(IEnumerable blobs, BlobContinuationToken continuationToken) - { - this.Results = blobs; - this.ContinuationToken = continuationToken; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - public IEnumerable Results { get; private set; } - - /// - /// Gets the continuation token used to retrieve the next segment of results. Returns null if there are no more results. - /// - /// The continuation token. - public BlobContinuationToken ContinuationToken { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobType.cs deleted file mode 100644 index 1804a0081bdac..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobType.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// The type of a blob. - /// - public enum BlobType - { - /// - /// Not specified. - /// - Unspecified, - - /// - /// A page blob. - /// - PageBlob, - - /// - /// A block blob. - /// - BlockBlob, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobWriteStreamBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobWriteStreamBase.cs deleted file mode 100644 index 59c568375903e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlobWriteStreamBase.cs +++ /dev/null @@ -1,316 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Text; - - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - internal abstract class BlobWriteStreamBase : -#if WINDOWS_RT - Stream -#else - CloudBlobStream -#endif - { - protected CloudBlockBlob blockBlob; - protected CloudPageBlob pageBlob; - protected long pageBlobSize; - protected bool newPageBlob; - protected long currentOffset; - protected long currentPageOffset; - protected int streamWriteSizeInBytes; - protected MultiBufferMemoryStream internalBuffer; - protected List blockList; - protected string blockIdPrefix; - protected AccessCondition accessCondition; - protected BlobRequestOptions options; - protected OperationContext operationContext; - protected CounterEvent noPendingWritesEvent; - protected MD5Wrapper blobMD5; - protected MD5Wrapper blockMD5; - protected AsyncSemaphore parallelOperationSemaphore; - protected volatile Exception lastException; - protected volatile bool committed; - protected bool disposed; - - /// - /// Initializes a new instance of the BlobWriteStreamBase class. - /// - /// The service client. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - private BlobWriteStreamBase(CloudBlobClient serviceClient, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base() - { - this.internalBuffer = new MultiBufferMemoryStream(serviceClient.BufferManager); - this.currentOffset = 0; - this.accessCondition = accessCondition; - this.options = options; - this.operationContext = operationContext; - this.noPendingWritesEvent = new CounterEvent(); - this.blobMD5 = this.options.StoreBlobContentMD5.Value ? new MD5Wrapper() : null; - this.blockMD5 = this.options.UseTransactionalMD5.Value ? new MD5Wrapper() : null; - this.parallelOperationSemaphore = new AsyncSemaphore(serviceClient.ParallelOperationThreadCount); - this.lastException = null; - this.committed = false; - this.disposed = false; - } - - /// - /// Initializes a new instance of the BlobWriteStreamBase class for a block blob. - /// - /// Blob reference to write to. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - protected BlobWriteStreamBase(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : this(blockBlob.ServiceClient, accessCondition, options, operationContext) - { - this.blockBlob = blockBlob; - this.blockList = new List(); - this.blockIdPrefix = Guid.NewGuid().ToString("N") + "-"; - this.streamWriteSizeInBytes = blockBlob.StreamWriteSizeInBytes; - } - - /// - /// Initializes a new instance of the BlobWriteStreamBase class for a page blob. - /// - /// Blob reference to write to. - /// Size of the page blob. - /// Use true if the page blob is newly created, false otherwise. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - protected BlobWriteStreamBase(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : this(pageBlob.ServiceClient, accessCondition, options, operationContext) - { - this.currentPageOffset = 0; - this.pageBlob = pageBlob; - this.pageBlobSize = pageBlobSize; - this.streamWriteSizeInBytes = pageBlob.StreamWriteSizeInBytes; - this.newPageBlob = createNew; - } - - protected ICloudBlob Blob - { - get - { - if (this.blockBlob != null) - { - return this.blockBlob; - } - else - { - return this.pageBlob; - } - } - } - - /// - /// Gets a value indicating whether the current stream supports reading. - /// - public override bool CanRead - { - get - { - return false; - } - } - - /// - /// Gets a value indicating whether the current stream supports seeking. - /// - public override bool CanSeek - { - get - { - return this.pageBlob != null; - } - } - - /// - /// Gets a value indicating whether the current stream supports writing. - /// - public override bool CanWrite - { - get - { - return true; - } - } - - /// - /// Gets the length in bytes of the stream. - /// - public override long Length - { - get - { - if (this.pageBlob != null) - { - return this.pageBlobSize; - } - else - { - throw new NotSupportedException(); - } - } - } - - /// - /// Gets or sets the position within the current stream. - /// - public override long Position - { - get - { - return this.currentOffset; - } - - set - { - this.Seek(value, SeekOrigin.Begin); - } - } - - /// - /// This operation is not supported in BlobWriteStreamBase. - /// - /// Not used. - /// Not used. - /// Not used. - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - /// - /// Calculates the new position within the current stream for a Seek operation. - /// - /// A byte offset relative to the origin parameter. - /// A value of type SeekOrigin indicating the reference - /// point used to obtain the new position. - /// The new position within the current stream. - protected long GetNewOffset(long offset, SeekOrigin origin) - { - if (!this.CanSeek) - { - throw new NotSupportedException(); - } - - if (this.lastException != null) - { - throw this.lastException; - } - - long newOffset; - switch (origin) - { - case SeekOrigin.Begin: - newOffset = offset; - break; - - case SeekOrigin.Current: - newOffset = this.currentOffset + offset; - break; - - case SeekOrigin.End: - newOffset = this.Length + offset; - break; - - default: - CommonUtility.ArgumentOutOfRange("origin", origin); - throw new ArgumentOutOfRangeException("origin"); - } - - CommonUtility.AssertInBounds("offset", newOffset, 0, this.Length); - - if ((newOffset % Constants.PageSize) != 0) - { - CommonUtility.ArgumentOutOfRange("offset", offset); - } - - return newOffset; - } - - /// - /// This operation is not supported in BlobWriteStreamBase. - /// - /// Not used. - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - /// - /// Generates a new block ID to be used for PutBlock. - /// - /// Base64 encoded block ID - protected string GetCurrentBlockId() - { - string blockIdSuffix = this.blockList.Count.ToString("D6", CultureInfo.InvariantCulture); - byte[] blockIdInBytes = Encoding.UTF8.GetBytes(this.blockIdPrefix + blockIdSuffix); - return Convert.ToBase64String(blockIdInBytes); - } - - /// - /// Releases the blob resources used by the Stream. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (this.blobMD5 != null) - { - this.blobMD5.Dispose(); - this.blobMD5 = null; - } - - if (this.blockMD5 != null) - { - this.blockMD5.Dispose(); - this.blockMD5 = null; - } - - if (this.internalBuffer != null) - { - this.internalBuffer.Dispose(); - this.internalBuffer = null; - } - - if (this.noPendingWritesEvent != null) - { - this.noPendingWritesEvent.Dispose(); - this.noPendingWritesEvent = null; - } - } - - base.Dispose(disposing); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockListingFilter.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockListingFilter.cs deleted file mode 100644 index 7c9bf566d0eea..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockListingFilter.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Indicates whether to list only committed blocks, only uncommitted blocks, or all blocks. - /// - public enum BlockListingFilter - { - /// - /// Committed blocks. - /// - Committed, - - /// - /// Uncommitted blocks. - /// - Uncommitted, - - /// - /// Both committed and uncommitted blocks. - /// - All - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockSearchMode.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockSearchMode.cs deleted file mode 100644 index 35ba6a78f39d3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/BlockSearchMode.cs +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Indicates which block lists should be searched to find a specified block. - /// - public enum BlockSearchMode - { - /// - /// Search the committed block list only. - /// - Committed, - - /// - /// Search the uncommitted block list only. - /// - Uncommitted, - - /// - /// Search the uncommitted block list first, and if the block is not found there, search - /// the committed block list. - /// - Latest - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobClient.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobClient.Common.cs deleted file mode 100644 index 6f8f3ac5ad233..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobClient.Common.cs +++ /dev/null @@ -1,334 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Provides a client-side logical representation of the Windows Azure Blob service. This client is used to configure and execute requests against 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 sealed partial class CloudBlobClient - { - /// - /// Constant for the max value of ParallelOperationThreadCount. - /// - private const int MaxParallelOperationThreadCount = 64; - - /// - /// Stores the default delimiter. - /// - private string defaultDelimiter; - - /// - /// Stores the parallelism factor. - /// - private int parallelismFactor = 1; - - /// - /// Default is 32 MB. - /// - private long singleBlobUploadThresholdInBytes = Constants.MaxSingleUploadBlobSize / 2; - - /// - /// The default server and client timeout interval. - /// - private TimeSpan? timeout; - - /// - /// Max execution time across all potential retries. - /// - private TimeSpan? maximumExecutionTime; - - private AuthenticationScheme authenticationScheme; - - /// - /// Initializes a new instance of the class using the specified Blob service endpoint - /// and anonymous credentials. - /// - /// The Blob service endpoint to use to create the client. - public CloudBlobClient(Uri baseUri) - : this(baseUri, null /* credentials */) - { - } - - /// - /// Initializes a new instance of the class using the specified Blob service endpoint - /// and account credentials. - /// - /// The Blob service endpoint to use to create the client. - /// The account credentials. - public CloudBlobClient(Uri baseUri, StorageCredentials credentials) - : this(null /* usePathStyleUris */, baseUri, credentials) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// True to use path style Uris. - /// The Blob service endpoint to use to create the client. - /// The account credentials. - internal CloudBlobClient(bool? usePathStyleUris, Uri baseUri, StorageCredentials credentials) - { - CommonUtility.AssertNotNull("baseUri", baseUri); - - if (credentials == null) - { - credentials = new StorageCredentials(); - } - - if (baseUri == null) - { - throw new ArgumentNullException("baseUri"); - } - - if (!baseUri.IsAbsoluteUri) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.RelativeAddressNotPermitted, baseUri.ToString()); - throw new ArgumentException(errorMessage, "baseUri"); - } - - this.BaseUri = baseUri; - this.Credentials = credentials; - this.RetryPolicy = new ExponentialRetry(); - this.ServerTimeout = Constants.DefaultServerSideTimeout; - this.DefaultDelimiter = NavigationHelper.Slash; - this.AuthenticationScheme = AuthenticationScheme.SharedKey; - - if (usePathStyleUris.HasValue) - { - this.UsePathStyleUris = usePathStyleUris.Value; - } - else - { - // Automatically decide whether to use host style uri or path style uri - this.UsePathStyleUris = CommonUtility.UsePathStyleAddressing(this.BaseUri); - } - } - - /// - /// Gets or sets a buffer manager that implements the interface, - /// specifying a buffer pool for use with operations against the Blob service client. - /// - public IBufferManager BufferManager { get; set; } - - /// - /// Gets the account credentials used to create the Blob service client. - /// - /// The account credentials. - public StorageCredentials Credentials { get; private set; } - - /// - /// Gets the base URI for the Blob service client. - /// - /// The base URI used to construct the Blob service client. - public Uri BaseUri { get; private set; } - - /// - /// Gets or sets the default retry policy for requests made via the Blob service client. - /// - /// The retry policy. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the default server and client timeout for requests made via the Blob service client. - /// - /// The server and client timeout interval. - public TimeSpan? ServerTimeout - { - get - { - return this.timeout; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.timeout = value; - } - } - - /// - /// Gets or sets the maximum execution time across all potential retries. - /// - /// The maximum execution time across all potential retries. - public TimeSpan? MaximumExecutionTime - { - get - { - return this.maximumExecutionTime; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.maximumExecutionTime = value; - } - } - - /// - /// Gets or sets the default delimiter that may be used to create a virtual directory structure of blobs. - /// - /// The default delimiter. - public string DefaultDelimiter - { - get - { - return this.defaultDelimiter; - } - - set - { - CommonUtility.AssertNotNullOrEmpty("DefaultDelimiter", value); - this.defaultDelimiter = value; - } - } - - /// - /// Gets or sets the maximum size of a blob in bytes that may be uploaded as a single blob. - /// - /// The maximum size of a blob, in bytes, that may be uploaded as a single blob, - /// ranging from between 1 and 64 MB inclusive. - public long SingleBlobUploadThresholdInBytes - { - get - { - return this.singleBlobUploadThresholdInBytes; - } - - set - { - CommonUtility.AssertInBounds("SingleBlobUploadThresholdInBytes", value, 1 * Constants.MB, Constants.MaxSingleUploadBlobSize); - this.singleBlobUploadThresholdInBytes = value; - } - } - - /// - /// Gets or sets the number of blocks that may be simultaneously uploaded when uploading a blob that is greater than - /// the value specified by the property in size. - /// - /// The number of parallel operations that may proceed. - public int ParallelOperationThreadCount - { - get - { - return this.parallelismFactor; - } - - set - { - CommonUtility.AssertInBounds("UploadParallelActiveTasks", value, 1, MaxParallelOperationThreadCount); - this.parallelismFactor = value; - } - } - - /// - /// Gets a value indicating whether the service client is used with Path style or Host style. - /// - /// Is true if use path style uris; otherwise, false. - internal bool UsePathStyleUris { get; private set; } - - /// - /// Returns a reference to the root container for this service client. - /// - /// A reference to the root container. - [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Reviewed")] - public CloudBlobContainer GetRootContainerReference() - { - return new CloudBlobContainer(NavigationHelper.RootContainerName, this); - } - - /// - /// Returns a reference to a object with the specified name. - /// - /// The name of the container, or an absolute URI to the container. - /// A reference to a container. - public CloudBlobContainer GetContainerReference(string containerName) - { - CommonUtility.AssertNotNullOrEmpty("containerName", containerName); - return new CloudBlobContainer(containerName, this); - } - - private ICanonicalizer GetCanonicalizer() - { - if (this.AuthenticationScheme == AuthenticationScheme.SharedKeyLite) - { - return SharedKeyLiteCanonicalizer.Instance; - } - - return SharedKeyCanonicalizer.Instance; - } - - /// - /// Parses the user prefix. - /// - /// The prefix. - /// Name of the container. - /// The listing prefix. - private static void ParseUserPrefix(string prefix, out string containerName, out string listingPrefix) - { - containerName = null; - listingPrefix = null; - - string[] prefixParts = prefix.Split(NavigationHelper.SlashAsSplitOptions, 2, StringSplitOptions.None); - if (prefixParts.Length == 1) - { - // No slash in prefix - // Case abc => container = $root, prefix=abc; Listing with prefix at root - listingPrefix = prefixParts[0]; - } - else - { - // Case "/abc" => container=$root, prefix=abc; Listing with prefix at root - // Case "abc/" => container=abc, no prefix; Listing all under a container - // Case "abc/def" => container = abc, prefix = def; Listing with prefix under a container - // Case "/" => container=$root, no prefix; Listing all under root - containerName = prefixParts[0]; - listingPrefix = prefixParts[1]; - } - - if (string.IsNullOrEmpty(containerName)) - { - containerName = NavigationHelper.RootContainerName; - } - - if (string.IsNullOrEmpty(listingPrefix)) - { - listingPrefix = null; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobContainer.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobContainer.Common.cs deleted file mode 100644 index 49dd2821c5714..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobContainer.Common.cs +++ /dev/null @@ -1,240 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Globalization; - - /// - /// Represents a container in the Windows Azure Blob service. - /// - public sealed partial class CloudBlobContainer - { - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the container. - public CloudBlobContainer(Uri containerAddress) - : this(containerAddress, null /* credentials */) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the container. - /// The account credentials. - public CloudBlobContainer(Uri containerAddress, StorageCredentials credentials) - { - this.ParseQueryAndVerify(containerAddress, credentials); - this.Metadata = new Dictionary(); - this.Properties = new BlobContainerProperties(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The container name. - /// A client object that specifies the endpoint for the Blob service. - internal CloudBlobContainer(string containerName, CloudBlobClient serviceClient) - : this(new BlobContainerProperties(), new Dictionary(), containerName, serviceClient) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The properties. - /// The metadata. - /// The container name. - /// The client to be used. - internal CloudBlobContainer(BlobContainerProperties properties, IDictionary metadata, string containerName, CloudBlobClient serviceClient) - { - this.Uri = NavigationHelper.AppendPathToUri(serviceClient.BaseUri, containerName); - this.ServiceClient = serviceClient; - this.Name = containerName; - this.Metadata = metadata; - this.Properties = properties; - } - - /// - /// Gets the service client for the container. - /// - /// A client object that specifies the endpoint for the Blob service. - public CloudBlobClient ServiceClient { get; private set; } - - /// - /// Gets the container's URI. - /// - /// The absolute URI to the container. - public Uri Uri { get; private set; } - - /// - /// Gets the name of the container. - /// - /// The container's name. - public string Name { get; private set; } - - /// - /// Gets the container's metadata. - /// - /// The container's metadata. - public IDictionary Metadata { get; private set; } - - /// - /// Gets the container's system properties. - /// - /// The container's properties. - public BlobContainerProperties Properties { get; private set; } - - /// - /// Parse URI for SAS (Shared Access Signature) information. - /// - /// The complete Uri. - /// The credentials to use. - private void ParseQueryAndVerify(Uri address, StorageCredentials credentials) - { - StorageCredentials parsedCredentials; - DateTimeOffset? parsedSnapshot; - this.Uri = NavigationHelper.ParseBlobQueryAndVerify(address, out parsedCredentials, out parsedSnapshot); - - if ((parsedCredentials != null) && (credentials != null) && !parsedCredentials.Equals(credentials)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleCredentialsProvided); - throw new ArgumentException(error); - } - - this.ServiceClient = new CloudBlobClient(NavigationHelper.GetServiceClientBaseAddress(this.Uri, null /* usePathStyleUris */), credentials ?? parsedCredentials); - this.Name = NavigationHelper.GetContainerNameFromContainerAddress(this.Uri, this.ServiceClient.UsePathStyleUris); - } - - /// - /// Returns the canonical name for shared access. - /// - /// The canonical name. - private string GetSharedAccessCanonicalName() - { - if (this.ServiceClient.UsePathStyleUris) - { - return this.Uri.AbsolutePath; - } - else - { - return NavigationHelper.GetCanonicalPathFromCreds(this.ServiceClient.Credentials, this.Uri.AbsolutePath); - } - } - - /// - /// Returns a shared access signature for the container. - /// - /// The access policy for the shared access signature. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy) - { - return this.GetSharedAccessSignature(policy, null /* groupPolicyIdentifier */); - } - - /// - /// Returns a shared access signature for the container. - /// - /// The access policy for the shared access signature. - /// A container-level access policy. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy, string groupPolicyIdentifier) - { - if (!this.ServiceClient.Credentials.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASWithoutAccountKey); - throw new InvalidOperationException(errorMessage); - } - - string resourceName = this.GetSharedAccessCanonicalName(); - StorageAccountKey accountKey = this.ServiceClient.Credentials.Key; - string signature = SharedAccessSignatureHelper.GetSharedAccessSignatureHashImpl(policy, groupPolicyIdentifier, resourceName, accountKey.KeyValue); - string accountKeyName = accountKey.KeyName; - - // Future resource type changes from "c" => "container" - UriQueryBuilder builder = SharedAccessSignatureHelper.GetSharedAccessSignatureImpl(policy, groupPolicyIdentifier, "c", signature, accountKeyName); - - return builder.ToString(); - } - - /// - /// Gets a reference to a page blob in this container. - /// - /// The name of the blob. - /// A reference to a page blob. - public CloudPageBlob GetPageBlobReference(string blobName) - { - return this.GetPageBlobReference(blobName, null /* snapshotTime */); - } - - /// - /// Returns a reference to a page blob in this virtual directory. - /// - /// The name of the page blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a page blob. - public CloudPageBlob GetPageBlobReference(string blobName, DateTimeOffset? snapshotTime) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - return new CloudPageBlob(blobName, snapshotTime, this); - } - - /// - /// Gets a reference to a block blob in this container. - /// - /// The name of the blob. - /// A reference to a block blob. - public CloudBlockBlob GetBlockBlobReference(string blobName) - { - return this.GetBlockBlobReference(blobName, null /* snapshotTime */); - } - - /// - /// Gets a reference to a block blob in this container. - /// - /// The name of the blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a block blob. - public CloudBlockBlob GetBlockBlobReference(string blobName, DateTimeOffset? snapshotTime) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - return new CloudBlockBlob(blobName, snapshotTime, this); - } - - /// - /// Gets a reference to a virtual blob directory beneath this container. - /// - /// The name of the virtual blob directory. - /// A reference to a virtual blob directory. - public CloudBlobDirectory GetDirectoryReference(string relativeAddress) - { - CommonUtility.AssertNotNullOrEmpty("relativeAddress", relativeAddress); - Uri blobDirectoryUri = NavigationHelper.AppendPathToUri(this.Uri, relativeAddress); - return new CloudBlobDirectory(blobDirectoryUri.AbsoluteUri, this); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobDirectory.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobDirectory.Common.cs deleted file mode 100644 index acb1128be4e68..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlobDirectory.Common.cs +++ /dev/null @@ -1,194 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - - /// - /// Represents a virtual directory of blobs on the client which emulates a hierarchical data store by using delimiter characters. - /// - /// Containers, which are encapsulated as objects, hold directories, and directories hold block blobs and page blobs. Directories can also contain sub-directories. - public sealed partial class CloudBlobDirectory : IListBlobItem - { - /// - /// Stores the parent directory. - /// - private CloudBlobDirectory parent; - - /// - /// Stores the prefix this directory represents. - /// - private string prefix; - - /// - /// Initializes a new instance of the class given an address and a client. - /// - /// The blob directory's address. - /// The container for the virtual directory. - internal CloudBlobDirectory(string absolutePath, CloudBlobContainer container) - { - CommonUtility.AssertNotNullOrEmpty("absolutePath", absolutePath); - CommonUtility.AssertNotNull("container", container); - - this.ServiceClient = container.ServiceClient; - this.Container = container; - - string delimiter = Uri.EscapeUriString(this.ServiceClient.DefaultDelimiter); - if (!absolutePath.EndsWith(delimiter, StringComparison.Ordinal)) - { - absolutePath = absolutePath + delimiter; - } - - this.Uri = NavigationHelper.AppendPathToUri(this.ServiceClient.BaseUri, absolutePath); - } - - /// - /// Gets the service client for the virtual directory. - /// - /// A client object that specifies the endpoint for the Windows Azure Blob service. - public CloudBlobClient ServiceClient { get; private set; } - - /// - /// Gets the URI that identifies the virtual directory. - /// - /// The URI to the virtual directory. - public Uri Uri { get; private set; } - - /// - /// Gets the container for the virtual directory. - /// - /// The container for the virtual directory. - public CloudBlobContainer Container { get; private set; } - - /// - /// Gets the parent directory for the virtual directory. - /// - /// The virtual directory's parent directory. - public CloudBlobDirectory Parent - { - get - { - if (this.parent == null) - { - Uri parentUri = NavigationHelper.GetParentAddress( - this.Uri, - this.ServiceClient.DefaultDelimiter, - this.ServiceClient.UsePathStyleUris); - - if (parentUri != null) - { - this.parent = new CloudBlobDirectory( - parentUri.AbsoluteUri, - this.Container); - } - } - - return this.parent; - } - } - - /// - /// Gets the prefix. - /// - /// The prefix. - public string Prefix - { - get - { - if (this.prefix == null) - { - this.InitializePrefix(); - } - - return this.prefix; - } - } - - /// - /// Gets a reference to a page blob in this virtual directory. - /// - /// The name of the blob. - /// A reference to a page blob. - public CloudPageBlob GetPageBlobReference(string blobName) - { - return this.GetPageBlobReference(blobName, null /* snapshotTime */); - } - - /// - /// Returns a reference to a page blob in this virtual directory. - /// - /// The name of the page blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a page blob. - public CloudPageBlob GetPageBlobReference(string blobName, DateTimeOffset? snapshotTime) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - - Uri blobUri = NavigationHelper.AppendPathToUri(this.Uri, blobName, this.ServiceClient.DefaultDelimiter); - return new CloudPageBlob(blobUri, snapshotTime, this.ServiceClient.Credentials); - } - - /// - /// Gets a reference to a block blob in this virtual directory. - /// - /// The name of the blob. - /// A reference to a block blob. - public CloudBlockBlob GetBlockBlobReference(string blobName) - { - return this.GetBlockBlobReference(blobName, null /* snapshotTime */); - } - - /// - /// Gets a reference to a block blob in this virtual directory. - /// - /// The name of the blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// A reference to a block blob. - public CloudBlockBlob GetBlockBlobReference(string blobName, DateTimeOffset? snapshotTime) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - - Uri blobUri = NavigationHelper.AppendPathToUri(this.Uri, blobName, this.ServiceClient.DefaultDelimiter); - return new CloudBlockBlob(blobUri, snapshotTime, this.ServiceClient.Credentials); - } - - /// - /// Returns a virtual subdirectory within this virtual directory. - /// - /// The name of the virtual subdirectory. - /// A object representing the virtual subdirectory. - public CloudBlobDirectory GetSubdirectoryReference(string itemName) - { - CommonUtility.AssertNotNull("itemName", itemName); - Uri subdirectoryUri = NavigationHelper.AppendPathToUri(this.Uri, itemName, this.ServiceClient.DefaultDelimiter); - return new CloudBlobDirectory(subdirectoryUri.AbsoluteUri, this.Container); - } - - /// - /// Initializes the prefix. - /// - private void InitializePrefix() - { - // Need to add the trailing slash or MakeRelativeUri will return the containerName again - Uri parentUri = new Uri(this.Container.Uri + NavigationHelper.Slash); - - this.prefix = Uri.UnescapeDataString(parentUri.MakeRelativeUri(this.Uri).OriginalString); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlockBlob.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlockBlob.Common.cs deleted file mode 100644 index c34d3c4541f1f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudBlockBlob.Common.cs +++ /dev/null @@ -1,438 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - - /// - /// Represents a blob that is uploaded as a set of blocks. - /// - public sealed partial class CloudBlockBlob : ICloudBlob - { - /// - /// Default is 4 MB. - /// - private int streamWriteSizeInBytes = Constants.DefaultWriteBlockSizeBytes; - - /// - /// Default is 4 MB. - /// - private int streamMinimumReadSizeInBytes = Constants.DefaultWriteBlockSizeBytes; - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - public CloudBlockBlob(Uri blobAbsoluteUri) - : this(blobAbsoluteUri, null /* credentials */) - { - } - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - /// The account credentials. - public CloudBlockBlob(Uri blobAbsoluteUri, StorageCredentials credentials) - : this(blobAbsoluteUri, null /* snapshotTime */, credentials) - { - } - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// The account credentials. - public CloudBlockBlob(Uri blobAbsoluteUri, DateTimeOffset? snapshotTime, StorageCredentials credentials) - { - this.attributes = new BlobAttributes(); - this.SnapshotTime = snapshotTime; - this.ParseQueryAndVerify(blobAbsoluteUri, credentials); - this.Properties.BlobType = BlobType.BlockBlob; - } - - /// - /// Initializes a new instance of the class using the specified blob name and - /// the parent container reference. - /// If snapshotTime is not null, the blob instance represents a Snapshot. - /// - /// Name of the blob. - /// Snapshot time in case the blob is a snapshot. - /// The reference to the parent container. - internal CloudBlockBlob(string blobName, DateTimeOffset? snapshotTime, CloudBlobContainer container) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - CommonUtility.AssertNotNull("container", container); - - this.attributes = new BlobAttributes(); - this.Uri = NavigationHelper.AppendPathToUri(container.Uri, blobName); - this.Name = blobName; - this.ServiceClient = container.ServiceClient; - this.container = container; - this.SnapshotTime = snapshotTime; - this.Properties.BlobType = BlobType.BlockBlob; - } - - /// - /// Initializes a new instance of the class. - /// - /// The attributes. - /// The service client. - internal CloudBlockBlob(BlobAttributes attributes, CloudBlobClient serviceClient) - { - this.attributes = attributes; - this.ServiceClient = serviceClient; - - this.ParseQueryAndVerify(this.Uri, this.ServiceClient.Credentials); - this.Properties.BlobType = BlobType.BlockBlob; - } - - /// - /// Stores the that contains this blob. - /// - private CloudBlobContainer container; - - /// - /// Stores the blob's parent . - /// - private CloudBlobDirectory parent; - - /// - /// Stores the blob's attributes. - /// - private readonly BlobAttributes attributes; - - /// - /// Gets the object that represents the Blob service. - /// - /// A client object that specifies the Blob service endpoint. - public CloudBlobClient ServiceClient { get; private set; } - - /// - /// Gets or sets the block size for writing to a block blob. - /// - /// The size of a block, in bytes, ranging from between 16 KB and 4 MB inclusive. - public int StreamWriteSizeInBytes - { - get - { - return this.streamWriteSizeInBytes; - } - - set - { - CommonUtility.AssertInBounds("StreamWriteSizeInBytes", value, 16 * Constants.KB, Constants.MaxBlockSize); - this.streamWriteSizeInBytes = value; - } - } - - /// - /// Gets or sets the minimum number of bytes to buffer when reading from a blob stream. - /// - /// The minimum number of bytes to buffer, being at least 16KB. - public int StreamMinimumReadSizeInBytes - { - get - { - return this.streamMinimumReadSizeInBytes; - } - - set - { - CommonUtility.AssertInBounds("StreamMinimumReadSizeInBytes", value, 16 * Constants.KB); - this.streamMinimumReadSizeInBytes = value; - } - } - - /// - /// Gets the blob's system properties. - /// - /// The blob's properties. - public BlobProperties Properties - { - get - { - return this.attributes.Properties; - } - } - - /// - /// Gets the user-defined metadata for the blob. - /// - /// The blob's metadata, as a collection of name-value pairs. - public IDictionary Metadata - { - get - { - return this.attributes.Metadata; - } - } - - /// - /// Gets the blob's URI. - /// - /// The absolute URI to the blob. - public Uri Uri - { - get - { - return this.attributes.Uri; - } - - private set - { - this.attributes.Uri = value; - } - } - - /// - /// Gets the date and time that the blob snapshot was taken, if this blob is a snapshot. - /// - /// The blob's snapshot time, if the blob is a snapshot. If the blob is not a snapshot, the value of this property is null. - public DateTimeOffset? SnapshotTime - { - get - { - return this.attributes.SnapshotTime; - } - - private set - { - this.attributes.SnapshotTime = value; - } - } - - /// - /// Gets a value indicating whether this blob is a snapshot. - /// - /// true if this blob is a snapshot; otherwise, false. - public bool IsSnapshot - { - get - { - return this.SnapshotTime.HasValue; - } - } - - /// - /// Gets the qualified URI to this blob if it is a snapshot. - /// - /// The qualified URI to the blob if the blob is a snapshot; otherwise, returns the absolute URI to the blob. - public Uri SnapshotQualifiedUri - { - get - { - if (this.SnapshotTime.HasValue) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value)); - return builder.AddToUri(this.Uri); - } - else - { - return this.Uri; - } - } - } - - /// - /// Gets the state of the most recent or pending copy operation. - /// - /// A object containing the copy state, or null if no copy blob state exists for this blob. - public CopyState CopyState - { - get - { - return this.attributes.CopyState; - } - } - - /// - /// Gets the type of the blob. - /// - /// The type of the blob. - public BlobType BlobType - { - get - { - return BlobType.BlockBlob; - } - } - - /// - /// Gets the blob's name. - /// - /// The blob's name. - public string Name { get; private set; } - - /// - /// Gets a object representing the blob's container. - /// - /// The blob's container. - public CloudBlobContainer Container - { - get - { - if (this.container == null) - { - this.container = this.ServiceClient.GetContainerReference( - NavigationHelper.GetContainerName(this.Uri, this.ServiceClient.UsePathStyleUris)); - } - - return this.container; - } - } - - /// - /// Gets the object representing the - /// virtual parent directory for the blob. - /// - /// The blob's virtual parent directory. - public CloudBlobDirectory Parent - { - get - { - if (this.parent == null) - { - Uri parentUri = NavigationHelper.GetParentAddress( - this.Uri, - this.ServiceClient.DefaultDelimiter, - this.ServiceClient.UsePathStyleUris); - - if (parentUri != null) - { - this.parent = new CloudBlobDirectory( - parentUri.AbsoluteUri, - this.Container); - } - } - - return this.parent; - } - } - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy) - { - return this.GetSharedAccessSignature(policy, null /* groupPolicyIdentifier */); - } - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A stored access policy. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy, string groupPolicyIdentifier) - { - if (!this.ServiceClient.Credentials.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASWithoutAccountKey); - throw new InvalidOperationException(errorMessage); - } - - if (this.SnapshotTime != null) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASForSnapshot); - throw new NotSupportedException(errorMessage); - } - - string resourceName = this.GetCanonicalName(true); - StorageAccountKey accountKey = this.ServiceClient.Credentials.Key; - string signature = SharedAccessSignatureHelper.GetSharedAccessSignatureHashImpl(policy, groupPolicyIdentifier, resourceName, accountKey.KeyValue); - - // Future resource type changes from "c" => "container" - UriQueryBuilder builder = SharedAccessSignatureHelper.GetSharedAccessSignatureImpl(policy, groupPolicyIdentifier, "b", signature, accountKey.KeyName); - - return builder.ToString(); - } - - /// - /// Gets the canonical name of the blob, formatted as /<account-name>/<container-name>/<blob-name>. - /// If ignoreSnapshotTime is false and this blob is a snapshot, the canonical name is augmented with a - /// query of the form ?snapshot=<snapshot-time>. - /// This is used by both Shared Access and Copy blob operations. - /// - /// Indicates if the snapshot time is ignored. - /// The canonical name of the blob. - private string GetCanonicalName(bool ignoreSnapshotTime) - { - string accountName = this.ServiceClient.Credentials.AccountName; - string containerName = this.Container.Name; - - // Replace \ with / for uri compatibility when running under .net 4.5. - string blobName = this.Name.Replace('\\', '/'); - - string canonicalName = string.Format(CultureInfo.InvariantCulture, "/{0}/{1}/{2}", accountName, containerName, blobName); - - if (!ignoreSnapshotTime && this.SnapshotTime != null) - { - canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value); - } - - return canonicalName; - } - - /// - /// Parse URI for SAS (Shared Access Signature) and snapshot information. - /// - /// The complete Uri. - /// The credentials to use. - private void ParseQueryAndVerify(Uri address, StorageCredentials credentials) - { - StorageCredentials parsedCredentials; - DateTimeOffset? parsedSnapshot; - this.Uri = NavigationHelper.ParseBlobQueryAndVerify(address, out parsedCredentials, out parsedSnapshot); - - if ((parsedCredentials != null) && (credentials != null) && !parsedCredentials.Equals(credentials)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleCredentialsProvided); - throw new ArgumentException(error); - } - - if (parsedSnapshot.HasValue && this.SnapshotTime.HasValue && !parsedSnapshot.Value.Equals(this.SnapshotTime.Value)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleSnapshotTimesProvided, parsedSnapshot, this.SnapshotTime); - throw new ArgumentException(error); - } - - if (parsedSnapshot.HasValue) - { - this.SnapshotTime = parsedSnapshot; - } - - this.ServiceClient = new CloudBlobClient(NavigationHelper.GetServiceClientBaseAddress(this.Uri, null /* usePathStyleUris */), credentials ?? parsedCredentials); - this.Name = NavigationHelper.GetBlobName(this.Uri, this.ServiceClient.UsePathStyleUris); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudPageBlob.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudPageBlob.Common.cs deleted file mode 100644 index 5fa37bc485757..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CloudPageBlob.Common.cs +++ /dev/null @@ -1,438 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - - /// - /// Represents a Windows Azure page blob. - /// - public sealed partial class CloudPageBlob : ICloudBlob - { - /// - /// Default is 4 MB. - /// - private int streamWriteSizeInBytes = Constants.DefaultWriteBlockSizeBytes; - - /// - /// Default is 4 MB. - /// - private int streamMinimumReadSizeInBytes = Constants.DefaultWriteBlockSizeBytes; - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - public CloudPageBlob(Uri blobAbsoluteUri) - : this(blobAbsoluteUri, null /* credentials */) - { - } - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - /// The account credentials. - public CloudPageBlob(Uri blobAbsoluteUri, StorageCredentials credentials) - : this(blobAbsoluteUri, null /* snapshotTime */, credentials) - { - } - - /// - /// Initializes a new instance of the class using an absolute URI to the blob. - /// - /// The absolute URI to the blob. - /// The snapshot timestamp, if the blob is a snapshot. - /// The account credentials. - public CloudPageBlob(Uri blobAbsoluteUri, DateTimeOffset? snapshotTime, StorageCredentials credentials) - { - this.attributes = new BlobAttributes(); - this.SnapshotTime = snapshotTime; - this.ParseQueryAndVerify(blobAbsoluteUri, credentials); - this.Properties.BlobType = BlobType.PageBlob; - } - - /// - /// Initializes a new instance of the class using the specified blob name and - /// the parent container reference. - /// If snapshotTime is not null, the blob instance represents a Snapshot. - /// - /// Name of the blob. - /// Snapshot time in case the blob is a snapshot. - /// The reference to the parent container. - internal CloudPageBlob(string blobName, DateTimeOffset? snapshotTime, CloudBlobContainer container) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - CommonUtility.AssertNotNull("container", container); - - this.attributes = new BlobAttributes(); - this.Uri = NavigationHelper.AppendPathToUri(container.Uri, blobName); - this.Name = blobName; - this.ServiceClient = container.ServiceClient; - this.container = container; - this.SnapshotTime = snapshotTime; - this.Properties.BlobType = BlobType.PageBlob; - } - - /// - /// Initializes a new instance of the class. - /// - /// The attributes. - /// The service client. - internal CloudPageBlob(BlobAttributes attributes, CloudBlobClient serviceClient) - { - this.attributes = attributes; - this.ServiceClient = serviceClient; - - this.ParseQueryAndVerify(this.Uri, this.ServiceClient.Credentials); - this.Properties.BlobType = BlobType.PageBlob; - } - - /// - /// Stores the that contains this blob. - /// - private CloudBlobContainer container; - - /// - /// Stores the blob's parent . - /// - private CloudBlobDirectory parent; - - /// - /// Stores the blob's attributes. - /// - private readonly BlobAttributes attributes; - - /// - /// Gets the object that represents the Blob service. - /// - /// A client object that specifies the Blob service endpoint. - public CloudBlobClient ServiceClient { get; private set; } - - /// - /// Gets or sets the number of bytes to buffer when writing to a page blob stream. - /// - /// The number of bytes to buffer, ranging from between 512 bytes and 4 MB inclusive. - public int StreamWriteSizeInBytes - { - get - { - return this.streamWriteSizeInBytes; - } - - set - { - CommonUtility.AssertInBounds("StreamWriteSizeInBytes", value, Constants.PageSize, Constants.MaxBlockSize); - this.streamWriteSizeInBytes = value; - } - } - - /// - /// Gets or sets the minimum number of bytes to buffer when reading from a blob stream. - /// - /// The minimum number of bytes to buffer, being at least 16KB. - public int StreamMinimumReadSizeInBytes - { - get - { - return this.streamMinimumReadSizeInBytes; - } - - set - { - CommonUtility.AssertInBounds("StreamMinimumReadSizeInBytes", value, 16 * Constants.KB); - this.streamMinimumReadSizeInBytes = value; - } - } - - /// - /// Gets the blob's system properties. - /// - /// The blob's properties. - public BlobProperties Properties - { - get - { - return this.attributes.Properties; - } - } - - /// - /// Gets the user-defined metadata for the blob. - /// - /// The blob's metadata, as a collection of name-value pairs. - public IDictionary Metadata - { - get - { - return this.attributes.Metadata; - } - } - - /// - /// Gets the blob's URI. - /// - /// The absolute URI to the blob. - public Uri Uri - { - get - { - return this.attributes.Uri; - } - - private set - { - this.attributes.Uri = value; - } - } - - /// - /// Gets the date and time that the blob snapshot was taken, if this blob is a snapshot. - /// - /// The blob's snapshot time, if the blob is a snapshot. If the blob is not a snapshot, the value of this property is null. - public DateTimeOffset? SnapshotTime - { - get - { - return this.attributes.SnapshotTime; - } - - private set - { - this.attributes.SnapshotTime = value; - } - } - - /// - /// Gets a value indicating whether this blob is a snapshot. - /// - /// true if this blob is a snapshot; otherwise, false. - public bool IsSnapshot - { - get - { - return this.SnapshotTime.HasValue; - } - } - - /// - /// Gets the qualified URI to this blob if it is a snapshot. - /// - /// The qualified URI to the blob if the blob is a snapshot; otherwise, returns the absolute URI to the blob. - public Uri SnapshotQualifiedUri - { - get - { - if (this.SnapshotTime.HasValue) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value)); - return builder.AddToUri(this.Uri); - } - else - { - return this.Uri; - } - } - } - - /// - /// Gets the state of the most recent or pending copy operation. - /// - /// A object containing the copy state, or null if no copy blob state exists for this blob. - public CopyState CopyState - { - get - { - return this.attributes.CopyState; - } - } - - /// - /// Gets the type of the blob. - /// - /// The type of the blob. - public BlobType BlobType - { - get - { - return BlobType.PageBlob; - } - } - - /// - /// Gets the blob's name. - /// - /// The blob's name. - public string Name { get; private set; } - - /// - /// Gets a object representing the blob's container. - /// - /// The blob's container. - public CloudBlobContainer Container - { - get - { - if (this.container == null) - { - this.container = this.ServiceClient.GetContainerReference( - NavigationHelper.GetContainerName(this.Uri, this.ServiceClient.UsePathStyleUris)); - } - - return this.container; - } - } - - /// - /// Gets the object representing the - /// virtual parent directory for the blob. - /// - /// The blob's virtual parent directory. - public CloudBlobDirectory Parent - { - get - { - if (this.parent == null) - { - Uri parentUri = NavigationHelper.GetParentAddress( - this.Uri, - this.ServiceClient.DefaultDelimiter, - this.ServiceClient.UsePathStyleUris); - - if (parentUri != null) - { - this.parent = new CloudBlobDirectory( - parentUri.AbsoluteUri, - this.Container); - } - } - - return this.parent; - } - } - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy) - { - return this.GetSharedAccessSignature(policy, null /* groupPolicyIdentifier */); - } - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A stored access policy. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessBlobPolicy policy, string groupPolicyIdentifier) - { - if (!this.ServiceClient.Credentials.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASWithoutAccountKey); - throw new InvalidOperationException(errorMessage); - } - - if (this.SnapshotTime != null) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASForSnapshot); - throw new NotSupportedException(errorMessage); - } - - string resourceName = this.GetCanonicalName(true); - StorageAccountKey accountKey = this.ServiceClient.Credentials.Key; - string signature = SharedAccessSignatureHelper.GetSharedAccessSignatureHashImpl(policy, groupPolicyIdentifier, resourceName, accountKey.KeyValue); - - // Future resource type changes from "c" => "container" - UriQueryBuilder builder = SharedAccessSignatureHelper.GetSharedAccessSignatureImpl(policy, groupPolicyIdentifier, "b", signature, accountKey.KeyName); - - return builder.ToString(); - } - - /// - /// Gets the canonical name of the blob, formatted as /<account-name>/<container-name>/<blob-name>. - /// If ignoreSnapshotTime is false and this blob is a snapshot, the canonical name is augmented with a - /// query of the form ?snapshot=<snapshot-time>. - /// This is used by both Shared Access and Copy blob operations. - /// - /// Indicates if the snapshot time is ignored. - /// The canonical name of the blob. - private string GetCanonicalName(bool ignoreSnapshotTime) - { - string accountName = this.ServiceClient.Credentials.AccountName; - string containerName = this.Container.Name; - - // Replace \ with / for uri compatibility when running under .net 4.5. - string blobName = this.Name.Replace('\\', '/'); - - string canonicalName = string.Format(CultureInfo.InvariantCulture, "/{0}/{1}/{2}", accountName, containerName, blobName); - - if (!ignoreSnapshotTime && this.SnapshotTime != null) - { - canonicalName += "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(this.SnapshotTime.Value); - } - - return canonicalName; - } - - /// - /// Parse URI for SAS (Shared Access Signature) and snapshot information. - /// - /// The complete Uri. - /// The credentials to use. - private void ParseQueryAndVerify(Uri address, StorageCredentials credentials) - { - StorageCredentials parsedCredentials; - DateTimeOffset? parsedSnapshot; - this.Uri = NavigationHelper.ParseBlobQueryAndVerify(address, out parsedCredentials, out parsedSnapshot); - - if ((parsedCredentials != null) && (credentials != null) && !parsedCredentials.Equals(credentials)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleCredentialsProvided); - throw new ArgumentException(error); - } - - if (parsedSnapshot.HasValue && this.SnapshotTime.HasValue && !parsedSnapshot.Value.Equals(this.SnapshotTime.Value)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleSnapshotTimesProvided, parsedSnapshot, this.SnapshotTime); - throw new ArgumentException(error); - } - - if (parsedSnapshot.HasValue) - { - this.SnapshotTime = parsedSnapshot; - } - - this.ServiceClient = new CloudBlobClient(NavigationHelper.GetServiceClientBaseAddress(this.Uri, null /* usePathStyleUris */), credentials ?? parsedCredentials); - this.Name = NavigationHelper.GetBlobName(this.Uri, this.ServiceClient.UsePathStyleUris); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerListingDetails.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerListingDetails.cs deleted file mode 100644 index d29b727b8c7ed..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerListingDetails.cs +++ /dev/null @@ -1,43 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Specifies which details to include when listing the containers in this storage account. - /// - [Flags] - public enum ContainerListingDetails - { - /// - /// No additional details. - /// - None = 0x0, - - /// - /// Retrieve container metadata. - /// - Metadata = 0x1, - - /// - /// Retrieve all available details. - /// - All = 0x1 - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerResultSegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerResultSegment.cs deleted file mode 100644 index f2cda2b4a81bb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ContainerResultSegment.cs +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System.Collections.Generic; - - /// - /// Represents a segment of results and contains continuation and pagination information. - /// - public sealed class ContainerResultSegment - { - internal ContainerResultSegment(IEnumerable containers, BlobContinuationToken continuationToken) - { - this.Results = containers; - this.ContinuationToken = continuationToken; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - public IEnumerable Results { get; private set; } - - /// - /// Gets the continuation token used to retrieve the next segment of results. - /// - /// The continuation token. - public BlobContinuationToken ContinuationToken { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyState.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyState.cs deleted file mode 100644 index 65c4a5956411f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyState.cs +++ /dev/null @@ -1,97 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Represents the attributes of a copy operation. - /// - public sealed class CopyState - { - /// - /// Gets the ID of the copy operation. - /// - /// A copy ID string. - public string CopyId - { - get; - internal set; - } - - /// - /// Gets the time the copy operation completed, and indicates whether completion was due to a successful copy, the cancelling of the operation, or a failure. - /// - /// A containing the completion time, or null if the operation has not completed. - public DateTimeOffset? CompletionTime - { - get; - internal set; - } - - /// - /// Gets the status of the copy operation. - /// - /// A enumeration indicating the status of the operation. - public CopyStatus Status - { - get; - internal set; - } - - /// - /// Gets the source URI of a copy operation. - /// - /// A indicating the source of a copy operation, or null. - public Uri Source - { - get; - internal set; - } - - /// - /// Gets the number of bytes copied in the operation so far. - /// - /// The number of bytes copied in the operation so far, or null. - public long? BytesCopied - { - get; - internal set; - } - - /// - /// Gets the total number of bytes in the source of the copy. - /// - /// The number of bytes in the source, or null. - public long? TotalBytes - { - get; - internal set; - } - - /// - /// Gets the description of the current status, if any. - /// - /// A status description string, or null. - public string StatusDescription - { - get; - internal set; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyStatus.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyStatus.cs deleted file mode 100644 index 8f2dac2c76e53..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/CopyStatus.cs +++ /dev/null @@ -1,50 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Represents the status of a copy blob operation. - /// - public enum CopyStatus - { - /// - /// The copy status is invalid. - /// - Invalid, - - /// - /// The copy operation is pending. - /// - Pending, - - /// - /// The copy operation succeeded. - /// - Success, - - /// - /// The copy operation has been aborted. - /// - Aborted, - - /// - /// The copy operation encountered an error. - /// - Failed - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/DeleteSnapshotsOption.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/DeleteSnapshotsOption.cs deleted file mode 100644 index 9050c481eb448..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/DeleteSnapshotsOption.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// The set of options describing delete operation. - /// - public enum DeleteSnapshotsOption - { - /// - /// Delete blobs but not snapshots. - /// - None, - - /// - /// Delete the blob and its snapshots. - /// - IncludeSnapshots, - - /// - /// Delete the blob's snapshots only. - /// - DeleteSnapshotsOnly - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ICloudBlob.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ICloudBlob.Common.cs deleted file mode 100644 index fd55df14a5251..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ICloudBlob.Common.cs +++ /dev/null @@ -1,115 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.Collections.Generic; - - /// - /// An interface required for Windows Azure blob types. The and classes implement the interface. - /// - public partial interface ICloudBlob : IListBlobItem - { - /// - /// Gets the blob item's name. - /// - /// The blob item's name. - string Name { get; } - - /// - /// Gets the object that represents the Blob service. - /// - /// A client object that specifies the Blob service endpoint. - CloudBlobClient ServiceClient { get; } - - /// - /// Gets or sets the number of bytes to buffer when writing to a page blob stream or - /// the block size for writing to a block blob. - /// - /// The number of bytes to buffer or the size of a block, in bytes. - int StreamWriteSizeInBytes { get; set; } - - /// - /// Gets or sets the minimum number of bytes to buffer when reading from a blob stream. - /// - /// The minimum number of bytes to buffer. - int StreamMinimumReadSizeInBytes { get; set; } - - /// - /// Gets the blob's system properties. - /// - /// The blob's properties. - BlobProperties Properties { get; } - - /// - /// Gets the user-defined metadata for the blob. - /// - /// The blob's metadata, as a collection of name-value pairs. - IDictionary Metadata { get; } - - /// - /// Gets the date and time that the blob snapshot was taken, if this blob is a snapshot. - /// - /// The blob's snapshot time if the blob is a snapshot; otherwise, null. - /// - /// If the blob is not a snapshot, the value of this property is null. - /// - DateTimeOffset? SnapshotTime { get; } - - /// - /// Gets a value indicating whether this blob is a snapshot. - /// - /// true if this blob is a snapshot; otherwise, false. - bool IsSnapshot { get; } - - /// - /// Gets the snapshot qualified URI to this blob. - /// - /// The blob's snapshot qualified URI if the blob is a snapshot; otherwise the absolute URI to the blob. - Uri SnapshotQualifiedUri { get; } - - /// - /// Gets the state of the most recent or pending copy operation. - /// - /// A object containing the copy state, or null if no copy blob state exists for this blob. - CopyState CopyState { get; } - - /// - /// Gets the type of the blob. - /// - /// The type of the blob. - BlobType BlobType { get; } - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - string GetSharedAccessSignature(SharedAccessBlobPolicy policy); - - /// - /// Returns a shared access signature for the blob. - /// - /// The access policy for the shared access signature. - /// A container-level access policy. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - string GetSharedAccessSignature(SharedAccessBlobPolicy policy, string groupPolicyIdentifier); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/IListBlobItem.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/IListBlobItem.cs deleted file mode 100644 index d76d4219037da..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/IListBlobItem.cs +++ /dev/null @@ -1,45 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Represents an item that may be returned by a blob listing operation. - /// - public interface IListBlobItem - { - /// - /// Gets the URI to the blob item. - /// - /// The blob item's URI. - Uri Uri { get; } - - /// - /// Gets the blob item's parent virtual directory. - /// - /// The blob item's parent virtual directory. - CloudBlobDirectory Parent { get; } - - /// - /// Gets the blob item's container. - /// - /// The blob item's container. - CloudBlobContainer Container { get; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseAction.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseAction.cs deleted file mode 100644 index 2e46db1697eeb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseAction.cs +++ /dev/null @@ -1,50 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Describes actions that can be performed on a lease. - /// - public enum LeaseAction - { - /// - /// Acquire the lease. - /// - Acquire, - - /// - /// Renew the lease. - /// - Renew, - - /// - /// Release the lease. - /// - Release, - - /// - /// Break the lease. - /// - Break, - - /// - /// Change the lease ID. - /// - Change, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseDuration.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseDuration.cs deleted file mode 100644 index 5f1926080655b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseDuration.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// The lease duration of a resource. - /// - public enum LeaseDuration - { - /// - /// The lease duration is not specified. - /// - Unspecified, - - /// - /// The lease duration is finite. - /// - Fixed, - - /// - /// The lease duration is infinite. - /// - Infinite - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseState.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseState.cs deleted file mode 100644 index cd0b089ab1aa8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseState.cs +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// The lease state of a resource. - /// - public enum LeaseState - { - /// - /// The lease state is not specified. - /// - Unspecified, - - /// - /// The lease is in the Available state. - /// - Available, - - /// - /// The lease is in the Leased state. - /// - Leased, - - /// - /// The lease is in the Expired state. - /// - Expired, - - /// - /// The lease is in the Breaking state. - /// - Breaking, - - /// - /// The lease is in the Broken state. - /// - Broken, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseStatus.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseStatus.cs deleted file mode 100644 index 45f33a4bf51ab..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/LeaseStatus.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// The lease status of a resource. - /// - public enum LeaseStatus - { - /// - /// The lease status is not specified. - /// - Unspecified, - - /// - /// The resource is locked. - /// - Locked, - - /// - /// The resource is available to be locked. - /// - Unlocked - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ListBlockItem.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ListBlockItem.cs deleted file mode 100644 index 7e03ffe5063c0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/ListBlockItem.cs +++ /dev/null @@ -1,43 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Represents a block retrieved from the blob's block list. - /// - public sealed class ListBlockItem - { - /// - /// Gets the name of the block. - /// - /// The block name. - public string Name { get; internal set; } - - /// - /// Gets the size of block in bytes. - /// - /// The block size. - public long Length { get; internal set; } - - /// - /// Gets a value indicating whether or not the block has been committed. - /// - /// True if the block has been committed; otherwise, false. - public bool Committed { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/PageRange.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/PageRange.cs deleted file mode 100644 index f51e7e6f8070a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/PageRange.cs +++ /dev/null @@ -1,59 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System.Globalization; - - /// - /// Represents a range of pages in a page blob. - /// - public sealed class PageRange - { - /// - /// Initializes a new instance of the class. - /// - /// The starting offset. - /// The ending offset. - public PageRange(long start, long end) - { - this.StartOffset = start; - this.EndOffset = end; - } - - /// - /// Gets the starting offset of the page range. - /// - /// The starting offset. - public long StartOffset { get; internal set; } - - /// - /// Gets the ending offset of the page range. - /// - /// The ending offset. - public long EndOffset { get; internal set; } - - /// - /// Returns the content of the page range as a string. - /// - /// The content of the page range. - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "bytes={0}-{1}", this.StartOffset, this.EndOffset); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobAccessPolicyResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobAccessPolicyResponse.cs deleted file mode 100644 index 333cc4a5e531c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobAccessPolicyResponse.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.IO; - using System.Xml.Linq; - - /// - /// Parses the response XML from an operation to set the access policy for a container. - /// - internal class BlobAccessPolicyResponse : AccessPolicyResponseBase - { - /// - /// Initializes a new instance of the BlobAccessPolicyResponse class. - /// - /// The stream to be parsed. - internal BlobAccessPolicyResponse(Stream stream) - : base(stream) - { - } - - /// - /// Parses the current element. - /// - /// The shared access policy element to parse. - /// The shared access policy. - protected override SharedAccessBlobPolicy ParseElement(XElement accessPolicyElement) - { - CommonUtility.AssertNotNull("accessPolicyElement", accessPolicyElement); - - SharedAccessBlobPolicy accessPolicy = new SharedAccessBlobPolicy(); - string sharedAccessStartTimeString = (string)accessPolicyElement.Element(Constants.Start); - if (!string.IsNullOrEmpty(sharedAccessStartTimeString)) - { - accessPolicy.SharedAccessStartTime = Uri.UnescapeDataString(sharedAccessStartTimeString).ToUTCTime(); - } - - string sharedAccessExpiryTimeString = (string)accessPolicyElement.Element(Constants.Expiry); - if (!string.IsNullOrEmpty(sharedAccessExpiryTimeString)) - { - accessPolicy.SharedAccessExpiryTime = Uri.UnescapeDataString(sharedAccessExpiryTimeString).ToUTCTime(); - } - - string permissionsString = (string)accessPolicyElement.Element(Constants.Permission); - if (!string.IsNullOrEmpty(permissionsString)) - { - accessPolicy.Permissions = SharedAccessBlobPolicy.PermissionsFromString(permissionsString); - } - - return accessPolicy; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobContainerEntry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobContainerEntry.cs deleted file mode 100644 index d378165608430..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobContainerEntry.cs +++ /dev/null @@ -1,68 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// -// Contains code for the CloudStorageAccount class. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - - /// - /// Represents a container item returned in the XML response for a container listing operation. - /// - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class BlobContainerEntry - { - /// - /// Initializes a new instance of the class. - /// - internal BlobContainerEntry() - { - } - - /// - /// Gets the user-defined metadata for the container. - /// - /// The container's metadata, as a collection of name-value pairs. - public IDictionary Metadata { get; internal set; } - - /// - /// Gets the container's system properties. - /// - /// The container's properties. - public BlobContainerProperties Properties { get; internal set; } - - /// - /// Gets the name of the container. - /// - /// The container's name. - public string Name { get; internal set; } - - /// - /// Gets the container's URI. - /// - /// The absolute URI to the container. - public Uri Uri { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobErrorCodeStrings.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobErrorCodeStrings.cs deleted file mode 100644 index 53f22edee07c0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobErrorCodeStrings.cs +++ /dev/null @@ -1,168 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// -// Contains code for the CloudStorageAccount class. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - /// - /// Provides error code strings that are specific to the Blob service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class BlobErrorCodeStrings - { - /// - /// Error code that may be returned when a block ID is invalid. - /// - public const string InvalidBlockId = "InvalidBlockId"; - - /// - /// Error code that may be returned when a blob with the specified address cannot be found. - /// - public const string BlobNotFound = "BlobNotFound"; - - /// - /// Error code that may be returned when a client attempts to create a blob that already exists. - /// - public const string BlobAlreadyExists = "BlobAlreadyExists"; - - /// - /// Error code that may be returned when the specified block or blob is invalid. - /// - public const string InvalidBlobOrBlock = "InvalidBlobOrBlock"; - - /// - /// Error code that may be returned when a block list is invalid. - /// - public const string InvalidBlockList = "InvalidBlockList"; - - /// - /// The specified container was not found. - /// - public const string ContainerNotFound = "ContainerNotFound"; - - /// - /// The specified container already exists. - /// - public const string ContainerAlreadyExists = "ContainerAlreadyExists"; - - /// - /// The specified container is disabled. - /// - public const string ContainerDisabled = "ContainerDisabled"; - - /// - /// The specified container is being deleted. - /// - public const string ContainerBeingDeleted = "ContainerBeingDeleted"; - - /// - /// Error code that may be returned when there is currently no lease on the blob. - /// - public const string LeaseNotPresentWithBlobOperation = "LeaseNotPresentWithBlobOperation"; - - /// - /// Error code that may be returned when there is currently no lease on the container. - /// - public const string LeaseNotPresentWithContainerOperation = "LeaseNotPresentWithContainerOperation"; - - /// - /// Error code that may be returned when a lease ID was specified, but the lease has expired. - /// - public const string LeaseLost = "LeaseLost"; - - /// - /// Error code that may be returned when the lease ID specified did not match the lease ID for the blob. - /// - public const string LeaseIdMismatchWithBlobOperation = "LeaseIdMismatchWithBlobOperation"; - - /// - /// Error code that may be returned when the lease ID specified did not match the lease ID for the container. - /// - public const string LeaseIdMismatchWithContainerOperation = "LeaseIdMismatchWithContainerOperation"; - - /// - /// Error code that may be returned when there is currently a lease on the resource and no lease ID was specified in the request. - /// - public const string LeaseIdMissing = "LeaseIdMissing"; - - /// - /// Error code that may be returned when there is currently no lease on the resource. - /// - public const string LeaseNotPresentWithLeaseOperation = "LeaseNotPresentWithLeaseOperation"; - - /// - /// Error code that may be returned when the lease ID specified did not match the lease ID. - /// - public const string LeaseIdMismatchWithLeaseOperation = "LeaseIdMismatchWithLeaseOperation"; - - /// - /// Error code that may be returned when there is already a lease present. - /// - public const string LeaseAlreadyPresent = "LeaseAlreadyPresent"; - - /// - /// Error code that may be returned when the lease has already been broken and cannot be broken again. - /// - public const string LeaseAlreadyBroken = "LeaseAlreadyBroken"; - - /// - /// Error code that may be returned when the lease ID matched, but the lease has been broken explicitly and cannot be renewed. - /// - public const string LeaseIsBrokenAndCannotBeRenewed = "LeaseIsBrokenAndCannotBeRenewed"; - - /// - /// Error code that may be returned when the lease ID matched, but the lease is breaking and cannot be acquired. - /// - public const string LeaseIsBreakingAndCannotBeAcquired = "LeaseIsBreakingAndCannotBeAcquired"; - - /// - /// Error code that may be returned when the lease ID matched, but the lease is breaking and cannot be changed. - /// - public const string LeaseIsBreakingAndCannotBeChanged = "LeaseIsBreakingAndCannotBeChanged"; - - /// - /// Error code that may be returned when the copy ID specified in an Abort Copy operation does not match the current pending copy ID. - /// - public const string CopyIdMismatch = "CopyIdMismatch"; - - /// - /// Error code that may be returned when an Abort Copy operation is called when there is no pending copy. - /// - public const string NoPendingCopyOperation = "NoPendingCopyOperation"; - - /// - /// Error code that may be returned when an attempt to modify the destination of a pending copy is made. - /// - public const string PendingCopyOperation = "PendingCopyOperation"; - - /// - /// Error code that may be returned when the source of a copy cannot be accessed. - /// - public const string CannotVerifyCopySource = "CannotVerifyCopySource"; - - /// - /// Error code that may be returned when the destination of a copy operation has a lease of fixed duration. - /// - public const string InfiniteLeaseDurationRequired = "InfiniteLeaseDurationRequired"; - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobHttpResponseParsers.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobHttpResponseParsers.Common.cs deleted file mode 100644 index 4ec8473b3c413..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobHttpResponseParsers.Common.cs +++ /dev/null @@ -1,203 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// -// Contains code for the CloudStorageAccount class. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Globalization; - using System.IO; - -#if WINDOWS_RT - internal -#else - public -#endif - static partial class BlobHttpResponseParsers - { - /// - /// Reads service properties from a stream. - /// - /// The stream from which to read the service properties. - /// The service properties stored in the stream. - public static ServiceProperties ReadServiceProperties(Stream inputStream) - { - return HttpResponseParsers.ReadServiceProperties(inputStream); - } - - /// - /// Gets a from a string. - /// - /// The lease status string. - /// A enumeration. - /// If a null or empty string is supplied, a status of is returned. - /// The string contains an unrecognized value. - internal static LeaseStatus GetLeaseStatus(string leaseStatus) - { - if (!string.IsNullOrEmpty(leaseStatus)) - { - switch (leaseStatus) - { - case Constants.LockedValue: - return LeaseStatus.Locked; - - case Constants.UnlockedValue: - return LeaseStatus.Unlocked; - - default: - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, SR.InvalidLeaseStatus, leaseStatus), "leaseStatus"); - } - } - - return LeaseStatus.Unspecified; - } - - /// - /// Gets a from a string. - /// - /// The lease state string. - /// A enumeration. - /// If a null or empty string is supplied, a status of is returned. - /// The string contains an unrecognized value. - internal static LeaseState GetLeaseState(string leaseState) - { - if (!string.IsNullOrEmpty(leaseState)) - { - switch (leaseState) - { - case Constants.LeaseAvailableValue: - return LeaseState.Available; - - case Constants.LeasedValue: - return LeaseState.Leased; - - case Constants.LeaseExpiredValue: - return LeaseState.Expired; - - case Constants.LeaseBreakingValue: - return LeaseState.Breaking; - - case Constants.LeaseBrokenValue: - return LeaseState.Broken; - - default: - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, SR.InvalidLeaseState, leaseState), "leaseState"); - } - } - - return LeaseState.Unspecified; - } - - /// - /// Gets a from a string. - /// - /// The lease duration string. - /// A enumeration. - /// If a null or empty string is supplied, a status of is returned. - /// The string contains an unrecognized value. - internal static LeaseDuration GetLeaseDuration(string leaseDuration) - { - if (!string.IsNullOrEmpty(leaseDuration)) - { - switch (leaseDuration) - { - case Constants.LeaseFixedValue: - return LeaseDuration.Fixed; - - case Constants.LeaseInfiniteValue: - return LeaseDuration.Infinite; - - default: - throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, SR.InvalidLeaseDuration, leaseDuration), "leaseDuration"); - } - } - - return LeaseDuration.Unspecified; - } - - /// - /// Builds a object from the given strings containing formatted copy information. - /// - /// The copy status, as a string. - /// The copy ID. - /// The source URI of the copy, as a string. - /// A string formatted as progressBytes/TotalBytes. - /// The copy completion time, as a string, or null. - /// The copy status description, if any. - /// A object populated from the given strings. - internal static CopyState GetCopyAttributes( - string copyStatusString, - string copyId, - string copySourceString, - string copyProgressString, - string copyCompletionTimeString, - string copyStatusDescription) - { - CopyState copyAttributes = new CopyState - { - CopyId = copyId, - StatusDescription = copyStatusDescription - }; - - switch (copyStatusString) - { - case Constants.CopySuccessValue: - copyAttributes.Status = CopyStatus.Success; - break; - - case Constants.CopyPendingValue: - copyAttributes.Status = CopyStatus.Pending; - break; - - case Constants.CopyAbortedValue: - copyAttributes.Status = CopyStatus.Aborted; - break; - - case Constants.CopyFailedValue: - copyAttributes.Status = CopyStatus.Failed; - break; - - default: - copyAttributes.Status = CopyStatus.Invalid; - break; - } - - if (!string.IsNullOrEmpty(copyProgressString)) - { - string[] progressSequence = copyProgressString.Split('/'); - copyAttributes.BytesCopied = long.Parse(progressSequence[0], CultureInfo.InvariantCulture); - copyAttributes.TotalBytes = long.Parse(progressSequence[1], CultureInfo.InvariantCulture); - } - - if (!string.IsNullOrEmpty(copySourceString)) - { - copyAttributes.Source = new Uri(copySourceString); - } - - if (!string.IsNullOrEmpty(copyCompletionTimeString)) - { - copyAttributes.CompletionTime = copyCompletionTimeString.ToUTCTime(); - } - - return copyAttributes; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobListingContext.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobListingContext.cs deleted file mode 100644 index 070b6593ada31..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobListingContext.cs +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - /// - /// Provides a set of parameters for a blob listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class BlobListingContext : ListingContext - { - /// - /// Initializes a new instance of the class. - /// - /// The blob prefix. - /// The maximum number of results to return. - /// The blob delimiter. - /// The include parameter. - public BlobListingContext(string prefix, int? maxResults, string delimiter, BlobListingDetails details) - : base(prefix, maxResults) - { - this.Delimiter = delimiter; - this.Details = details; - } - - /// - /// Gets or sets the delimiter for a blob listing operation. - /// - /// The delimiter to use to traverse the virtual hierarchy of blobs. - /// - /// The delimiter parameter enables the caller to traverse the blob namespace by using a user-configured delimiter. - /// Using this parameter, it is possible to traverse a virtual hierarchy of blobs as though it were a file system. - /// - public string Delimiter { get; set; } - - /// - /// Gets or sets the details for the listing operation, which indicates the types of data to include in the - /// response. - /// - /// The details to include in the listing operation. - /// - /// The include parameter specifies that the response should include one or more of the following subsets: snapshots, - /// metadata, uncommitted blobs. - /// - public BlobListingDetails Details { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobRequest.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobRequest.cs deleted file mode 100644 index 47eb0bcf49533..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/BlobRequest.cs +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Text; - using System.Xml; - - /// - /// Provides a set of helper methods for constructing a request against the Blob service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class BlobRequest - { - /// - /// Converts the date time to snapshot string. - /// - /// The date time. - /// The converted string. - internal static string ConvertDateTimeToSnapshotString(DateTimeOffset dateTime) - { - return dateTime.UtcDateTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffff'Z'", CultureInfo.InvariantCulture); - } - - /// - /// Writes a collection of shared access policies to the specified stream in XML format. - /// - /// A collection of shared access policies. - /// An output stream. - public static void WriteSharedAccessIdentifiers(SharedAccessBlobPolicies sharedAccessPolicies, Stream outputStream) - { - Request.WriteSharedAccessIdentifiers( - sharedAccessPolicies, - outputStream, - (policy, writer) => - { - writer.WriteElementString( - Constants.Start, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessStartTime)); - writer.WriteElementString( - Constants.Expiry, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessExpiryTime)); - writer.WriteElementString( - Constants.Permission, - SharedAccessBlobPolicy.PermissionsToString(policy.Permissions)); - }); - } - - /// - /// Writes the body of the block list to the specified stream in XML format. - /// - /// An enumerable collection of objects. - /// The stream to which the block list is written. - public static void WriteBlockListBody(IEnumerable blocks, Stream outputStream) - { - CommonUtility.AssertNotNull("blocks", blocks); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = Encoding.UTF8; - using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) - { - writer.WriteStartElement(Constants.BlockListElement); - - foreach (PutBlockListItem block in blocks) - { - if (block.SearchMode == BlockSearchMode.Committed) - { - writer.WriteElementString(Constants.CommittedElement, block.Id); - } - else if (block.SearchMode == BlockSearchMode.Uncommitted) - { - writer.WriteElementString(Constants.UncommittedElement, block.Id); - } - else if (block.SearchMode == BlockSearchMode.Latest) - { - writer.WriteElementString(Constants.LatestElement, block.Id); - } - } - - writer.WriteEndDocument(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ContainerHttpResponseParsers.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ContainerHttpResponseParsers.Common.cs deleted file mode 100644 index 7701aa19f957f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ContainerHttpResponseParsers.Common.cs +++ /dev/null @@ -1,76 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - -#if WINDOWS_RT - internal -#else - public -#endif - static partial class ContainerHttpResponseParsers - { - /// - /// Reads the share access policies from a stream in XML. - /// - /// The stream of XML policies. - /// The permissions object to which the policies are to be written. - public static void ReadSharedAccessIdentifiers(Stream inputStream, BlobContainerPermissions permissions) - { - CommonUtility.AssertNotNull("permissions", permissions); - - Response.ReadSharedAccessIdentifiers(permissions.SharedAccessPolicies, new BlobAccessPolicyResponse(inputStream)); - } - - /// - /// Converts the ACL string to a object. - /// - /// The string to convert. - /// The resulting object. - [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "ToLower(CultureInfo) is not present in RT and ToLowerInvariant() also violates FxCop")] - private static BlobContainerPublicAccessType GetContainerAcl(string acl) - { - BlobContainerPublicAccessType accessType = BlobContainerPublicAccessType.Off; - - if (!string.IsNullOrEmpty(acl)) - { - switch (acl.ToLower()) - { - case "container": - accessType = BlobContainerPublicAccessType.Container; - break; - case "blob": - accessType = BlobContainerPublicAccessType.Blob; - break; - default: - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.InvalidAclType, acl); - throw new InvalidOperationException(errorMessage); - } - } - - return accessType; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetBlockListResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetBlockListResponse.cs deleted file mode 100644 index 53ec166542884..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetBlockListResponse.cs +++ /dev/null @@ -1,156 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.Collections.Generic; - using System.IO; - - /// - /// Provides methods for parsing the response from an operation to return a block list. - /// -#if WINDOWS_RT - internal -#else - public -#endif - class GetBlockListResponse : ResponseParsingBase - { - /// - /// Initializes a new instance of the class. - /// - /// The stream to be parsed. - public GetBlockListResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets an enumerable collection of objects from the response. - /// - /// An enumerable collection of objects. - public IEnumerable Blocks - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Reads a block item for block listing. - /// - /// Whether we are currently listing committed blocks or not - /// Block listing entry - private ListBlockItem ParseBlockItem(bool committed) - { - ListBlockItem block = new ListBlockItem() - { - Committed = committed, - }; - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.SizeElement: - block.Length = reader.ReadElementContentAsLong(); - break; - - case Constants.NameElement: - block.Name = reader.ReadElementContentAsString(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - - return block; - } - - /// - /// Parses the XML response returned by an operation to retrieve a list of blocks. - /// - /// An enumerable collection of objects. - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.BlockListElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.CommittedBlocksElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement(Constants.BlockElement)) - { - yield return this.ParseBlockItem(true); - } - - this.reader.ReadEndElement(); - break; - - case Constants.UncommittedBlocksElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement(Constants.BlockElement)) - { - yield return this.ParseBlockItem(false); - } - - this.reader.ReadEndElement(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.allObjectsParsed = true; - this.reader.ReadEndElement(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetPageRangesResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetPageRangesResponse.cs deleted file mode 100644 index bff376c62a0ef..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/GetPageRangesResponse.cs +++ /dev/null @@ -1,121 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.Collections.Generic; - using System.IO; - - /// - /// Provides methods for parsing the response from an operation to get a range of pages for a page blob. - /// -#if WINDOWS_DESKTOP - public -#else - internal -#endif - sealed class GetPageRangesResponse : ResponseParsingBase - { - /// - /// Initializes a new instance of the class. - /// - /// The stream of page ranges to be parsed. - public GetPageRangesResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets an enumerable collection of objects from the response. - /// - /// An enumerable collection of objects. - public IEnumerable PageRanges - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Reads a page range. - /// - /// Page range entry - private PageRange ParsePageRange() - { - long start = 0L; - long end = 0L; - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.StartElement: - start = reader.ReadElementContentAsLong(); - break; - - case Constants.EndElement: - end = reader.ReadElementContentAsLong(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - - return new PageRange(start, end); - } - - /// - /// Parses the XML response for an operation to get a range of pages for a page blob. - /// - /// An enumerable collection of objects. - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.PageListElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement(Constants.PageRangeElement)) - { - yield return this.ParsePageRange(); - } - - this.allObjectsParsed = true; - this.reader.ReadEndElement(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/IListBlobEntry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/IListBlobEntry.cs deleted file mode 100644 index 1d01ad67166e3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/IListBlobEntry.cs +++ /dev/null @@ -1,31 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - /// - /// Represents an item that may be returned by a blob listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - interface IListBlobEntry - { - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobEntry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobEntry.cs deleted file mode 100644 index ec969204f4da0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobEntry.cs +++ /dev/null @@ -1,118 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - - /// - /// Represents a blob item returned in the XML response for a blob listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class ListBlobEntry : IListBlobEntry - { - /// - /// Initializes a new instance of the class. - /// - /// The name of the blob. - /// The blob's attributes. - internal ListBlobEntry(string name, BlobAttributes attributes) - { - this.Name = name; - this.Attributes = attributes; - } - - /// - /// Stores the blob item's attributes. - /// - internal BlobAttributes Attributes { get; private set; } - - /// - /// Gets the name of the blob item. - /// - /// The name of the blob item. - public string Name { get; private set; } - - /// - /// Gets the blob item's system properties. - /// - /// The blob item's properties. - public BlobProperties Properties - { - get - { - return this.Attributes.Properties; - } - } - - /// - /// Gets the user-defined metadata for the blob item. - /// - /// The blob item's metadata, as a collection of name-value pairs. - public IDictionary Metadata - { - get - { - return this.Attributes.Metadata; - } - } - - /// - /// Gets the blob item's URI. - /// - /// The absolute URI to the blob item. - public Uri Uri - { - get - { - return this.Attributes.Uri; - } - } - - /// - /// Gets the date and time that the blob snapshot was taken, if this blob is a snapshot. - /// - /// The blob's snapshot time if the blob is a snapshot; otherwise, null. - /// - /// If the blob is not a snapshot, the value of this property is null. - /// - public DateTimeOffset? SnapshotTime - { - get - { - return this.Attributes.SnapshotTime; - } - } - - /// - /// Gets the state of the most recent or pending copy operation. - /// - /// A object containing the copy state, or null if no copy blob state exists for this blob. - public CopyState CopyState - { - get - { - return this.Attributes.CopyState; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobPrefixEntry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobPrefixEntry.cs deleted file mode 100644 index 4fd6b93289c4a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobPrefixEntry.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - /// - /// Represents the blob name prefix that is returned in the XML response for a blob listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class ListBlobPrefixEntry : IListBlobEntry - { - /// - /// Gets the blob name prefix. - /// - /// The blob name prefix. - public string Name - { - get; - internal set; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobsResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobsResponse.cs deleted file mode 100644 index 51322791b06b0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListBlobsResponse.cs +++ /dev/null @@ -1,510 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - - /// - /// Provides methods for parsing the response from a blob listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class ListBlobsResponse : ResponseParsingBase - { - /// - /// Stores the blob prefix. - /// - private string prefix; - - /// - /// Signals when the blob prefix can be consumed. - /// - private bool prefixConsumable; - - /// - /// Stores the marker. - /// - private string marker; - - /// - /// Signals when the marker can be consumed. - /// - private bool markerConsumable; - - /// - /// Stores the blob delimiter. - /// - private string delimiter; - - /// - /// Signals when the blob delimiter can be consumed. - /// - private bool delimiterConsumable; - - /// - /// Stores the max results. - /// - private int maxResults; - - /// - /// Signals when the max results can be consumed. - /// - private bool maxResultsConsumable; - - /// - /// Stores the next marker. - /// - private string nextMarker; - - /// - /// Signals when the next marker can be consumed. - /// - private bool nextMarkerConsumable; - - /// - /// Initializes a new instance of the class. - /// - /// The stream to be parsed. - public ListBlobsResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets the listing context from the XML response. - /// - /// A set of parameters for the listing operation. - public BlobListingContext ListingContext - { - get - { - string prefixString = this.Prefix; - int maximumResults = this.MaxResults; - string delimiterString = this.Delimiter; - string nextMarkerString = this.NextMarker; - BlobListingContext listingContext = new BlobListingContext( - prefixString, - maximumResults, - delimiterString, - BlobListingDetails.None); - listingContext.Marker = nextMarkerString; - return listingContext; - } - } - - /// - /// Gets an enumerable collection of objects that implement from the response. - /// - /// An enumerable collection of objects that implement . - public IEnumerable Blobs - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Gets the Prefix value provided for the listing operation from the XML response. - /// - /// The Prefix value. - public string Prefix - { - get - { - this.Variable(ref this.prefixConsumable); - - return this.prefix; - } - } - - /// - /// Gets the Marker value provided for the listing operation from the XML response. - /// - /// The Marker value. - public string Marker - { - get - { - this.Variable(ref this.markerConsumable); - - return this.marker; - } - } - - /// - /// Gets the Delimiter value provided for the listing operation from the XML response. - /// - /// The Delimiter value. - public string Delimiter - { - get - { - this.Variable(ref this.delimiterConsumable); - - return this.delimiter; - } - } - - /// - /// Gets the MaxResults value provided for the listing operation from the XML response. - /// - /// The MaxResults value. - public int MaxResults - { - get - { - this.Variable(ref this.maxResultsConsumable); - - return this.maxResults; - } - } - - /// - /// Gets the NextMarker value from the XML response, if the listing was not complete. - /// - /// The NextMarker value. - public string NextMarker - { - get - { - this.Variable(ref this.nextMarkerConsumable); - - return this.nextMarker; - } - } - - /// - /// Parses a blob entry in a blob listing response. - /// - /// Blob listing entry - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Reviewed.")] - private IListBlobEntry ParseBlobEntry() - { - BlobAttributes blob = new BlobAttributes(); - string url = null; - string name = null; - - // copy blob attribute strings - string copyId = null; - string copyStatus = null; - string copyCompletionTime = null; - string copyProgress = null; - string copySource = null; - string copyStatusDescription = null; - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.UrlElement: - url = reader.ReadElementContentAsString(); - break; - - case Constants.NameElement: - name = reader.ReadElementContentAsString(); - break; - - case Constants.SnapshotElement: - blob.SnapshotTime = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.PropertiesElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.LastModifiedElement: - blob.Properties.LastModified = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.EtagElement: - blob.Properties.ETag = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", reader.ReadElementContentAsString()); - break; - - case Constants.ContentLengthElement: - blob.Properties.Length = reader.ReadElementContentAsLong(); - break; - - case Constants.CacheControlElement: - blob.Properties.CacheControl = reader.ReadElementContentAsString(); - break; - - case Constants.ContentTypeElement: - blob.Properties.ContentType = reader.ReadElementContentAsString(); - break; - - case Constants.ContentEncodingElement: - blob.Properties.ContentEncoding = reader.ReadElementContentAsString(); - break; - - case Constants.ContentLanguageElement: - blob.Properties.ContentLanguage = reader.ReadElementContentAsString(); - break; - - case Constants.ContentMD5Element: - blob.Properties.ContentMD5 = reader.ReadElementContentAsString(); - break; - - case Constants.BlobTypeElement: - string blobTypeString = reader.ReadElementContentAsString(); - switch (blobTypeString) - { - case Constants.BlockBlobValue: - blob.Properties.BlobType = BlobType.BlockBlob; - break; - - case Constants.PageBlobValue: - blob.Properties.BlobType = BlobType.PageBlob; - break; - } - - break; - - case Constants.LeaseStatusElement: - blob.Properties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(reader.ReadElementContentAsString()); - break; - - case Constants.LeaseStateElement: - blob.Properties.LeaseState = BlobHttpResponseParsers.GetLeaseState(reader.ReadElementContentAsString()); - break; - - case Constants.LeaseDurationElement: - blob.Properties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(reader.ReadElementContentAsString()); - break; - - case Constants.CopyIdElement: - copyId = reader.ReadElementContentAsString(); - break; - - case Constants.CopyCompletionTimeElement: - copyCompletionTime = reader.ReadElementContentAsString(); - break; - - case Constants.CopyStatusElement: - copyStatus = reader.ReadElementContentAsString(); - break; - - case Constants.CopyProgressElement: - copyProgress = reader.ReadElementContentAsString(); - break; - - case Constants.CopySourceElement: - copySource = reader.ReadElementContentAsString(); - break; - - case Constants.CopyStatusDescriptionElement: - copyStatusDescription = reader.ReadElementContentAsString(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - break; - - case Constants.MetadataElement: - blob.Metadata = Response.ParseMetadata(this.reader); - break; - - default: - this.reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - - int blobNameSectionIndex = url.LastIndexOf(NavigationHelper.Slash + name, StringComparison.Ordinal); - string baseUri = url.Substring(0, blobNameSectionIndex + 1); - UriBuilder ub = new UriBuilder(baseUri); - ub.Path += Uri.EscapeUriString(name); - if (baseUri.Length + name.Length < url.Length) - { - // it's a url for snapshot. - // Snapshot blob URI example:http://.blob.core.windows.net//?snapshot=2009-12-03T15%3a26%3a19.4466877Z - ub.Query = url.Substring(baseUri.Length + name.Length + 1); - } - - blob.Uri = ub.Uri; - - if (!string.IsNullOrEmpty(copyStatus)) - { - blob.CopyState = BlobHttpResponseParsers.GetCopyAttributes( - copyStatus, - copyId, - copySource, - copyProgress, - copyCompletionTime, - copyStatusDescription); - } - - return new ListBlobEntry(name, blob); - } - - /// - /// Parses a blob prefix entry in a blob listing response. - /// - /// Blob listing entry - private IListBlobEntry ParseBlobPrefixEntry() - { - ListBlobPrefixEntry commonPrefix = new ListBlobPrefixEntry(); - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.NameElement: - commonPrefix.Name = reader.ReadElementContentAsString(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - - return commonPrefix; - } - - /// - /// Parses the response XML for a blob listing operation. - /// - /// An enumerable collection of objects that implement . - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.EnumerationResultsElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.DelimiterElement: - this.delimiter = reader.ReadElementContentAsString(); - this.delimiterConsumable = true; - yield return null; - break; - - case Constants.MarkerElement: - this.marker = reader.ReadElementContentAsString(); - this.markerConsumable = true; - yield return null; - break; - - case Constants.NextMarkerElement: - this.nextMarker = reader.ReadElementContentAsString(); - this.nextMarkerConsumable = true; - yield return null; - break; - - case Constants.MaxResultsElement: - this.maxResults = reader.ReadElementContentAsInt(); - this.maxResultsConsumable = true; - yield return null; - break; - - case Constants.PrefixElement: - this.prefix = reader.ReadElementContentAsString(); - this.prefixConsumable = true; - yield return null; - break; - - case Constants.BlobsElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - switch (this.reader.Name) - { - case Constants.BlobElement: - yield return this.ParseBlobEntry(); - break; - - case Constants.BlobPrefixElement: - yield return this.ParseBlobPrefixEntry(); - break; - } - } - - this.reader.ReadEndElement(); - this.allObjectsParsed = true; - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListContainersResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListContainersResponse.cs deleted file mode 100644 index c04fce23a8fd1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/ListContainersResponse.cs +++ /dev/null @@ -1,339 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - - /// - /// Provides methods for parsing the response from a container listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class ListContainersResponse : ResponseParsingBase - { - /// - /// Stores the container prefix. - /// - private string prefix; - - /// - /// Signals when the container prefix can be consumed. - /// - private bool prefixConsumable; - - /// - /// Stores the marker. - /// - private string marker; - - /// - /// Signals when the marker can be consumed. - /// - private bool markerConsumable; - - /// - /// Stores the max results. - /// - private int maxResults; - - /// - /// Signals when the max results can be consumed. - /// - private bool maxResultsConsumable; - - /// - /// Stores the next marker. - /// - private string nextMarker; - - /// - /// Signals when the next marker can be consumed. - /// - private bool nextMarkerConsumable; - - /// - /// Initializes a new instance of the class. - /// - /// The stream to be parsed. - public ListContainersResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets the listing context from the XML response. - /// - /// A set of parameters for the listing operation. - public ListingContext ListingContext - { - get - { - // Force a parsing in order - ListingContext listingContext = new ListingContext(this.Prefix, this.MaxResults); - listingContext.Marker = this.NextMarker; - return listingContext; - } - } - - /// - /// Gets an enumerable collection of objects from the response. - /// - /// An enumerable collection of objects. - public IEnumerable Containers - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Gets the Prefix value provided for the listing operation from the XML response. - /// - /// The Prefix value. - public string Prefix - { - get - { - this.Variable(ref this.prefixConsumable); - - return this.prefix; - } - } - - /// - /// Gets the Marker value provided for the listing operation from the XML response. - /// - /// The Marker value. - public string Marker - { - get - { - this.Variable(ref this.markerConsumable); - - return this.marker; - } - } - - /// - /// Gets the MaxResults value provided for the listing operation from the XML response. - /// - /// The MaxResults value. - public int MaxResults - { - get - { - this.Variable(ref this.maxResultsConsumable); - - return this.maxResults; - } - } - - /// - /// Gets the NextMarker value from the XML response, if the listing was not complete. - /// - /// The NextMarker value. - public string NextMarker - { - get - { - this.Variable(ref this.nextMarkerConsumable); - - return this.nextMarker; - } - } - - /// - /// Reads a container entry completely including its properties and metadata. - /// - /// Container listing entry - private BlobContainerEntry ParseContainerEntry() - { - Uri uri = null; - string name = null; - IDictionary metadata = null; - BlobContainerProperties containerProperties = new BlobContainerProperties(); - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.UrlElement: - string url = this.reader.ReadElementContentAsString(); - Uri.TryCreate(url, UriKind.Absolute, out uri); - break; - - case Constants.NameElement: - name = this.reader.ReadElementContentAsString(); - break; - - case Constants.PropertiesElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.LastModifiedElement: - containerProperties.LastModified = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.EtagElement: - containerProperties.ETag = reader.ReadElementContentAsString(); - break; - - case Constants.LeaseStatusElement: - containerProperties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(reader.ReadElementContentAsString()); - break; - - case Constants.LeaseStateElement: - containerProperties.LeaseState = BlobHttpResponseParsers.GetLeaseState(reader.ReadElementContentAsString()); - break; - - case Constants.LeaseDurationElement: - containerProperties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(reader.ReadElementContentAsString()); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - break; - - case Constants.MetadataElement: - metadata = Response.ParseMetadata(this.reader); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - - if (metadata == null) - { - metadata = new Dictionary(); - } - - return new BlobContainerEntry - { - Properties = containerProperties, - Name = name, - Uri = uri, - Metadata = metadata, - }; - } - - /// - /// Parses the response XML for a container listing operation. - /// - /// An enumerable collection of objects. - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.EnumerationResultsElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.MarkerElement: - this.marker = this.reader.ReadElementContentAsString(); - this.markerConsumable = true; - yield return null; - break; - - case Constants.NextMarkerElement: - this.nextMarker = this.reader.ReadElementContentAsString(); - this.nextMarkerConsumable = true; - yield return null; - break; - - case Constants.MaxResultsElement: - this.maxResults = this.reader.ReadElementContentAsInt(); - this.maxResultsConsumable = true; - yield return null; - break; - - case Constants.PrefixElement: - this.prefix = this.reader.ReadElementContentAsString(); - this.prefixConsumable = true; - yield return null; - break; - - case Constants.ContainersElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement(Constants.ContainerElement)) - { - yield return this.ParseContainerEntry(); - } - - this.reader.ReadEndElement(); - this.allObjectsParsed = true; - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PageWrite.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PageWrite.cs deleted file mode 100644 index 682fe67fc66ea..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PageWrite.cs +++ /dev/null @@ -1,35 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - /// - /// Describes actions that may be used for writing to a page blob or clearing a set of pages. - /// - public enum PageWrite - { - /// - /// Update the page with new data. - /// - Update, - - /// - /// Clear the page. - /// - Clear - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PutBlockListItem.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PutBlockListItem.cs deleted file mode 100644 index 260450cd903ef..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/Protocol/PutBlockListItem.cs +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - /// - /// Represents a block in a block list. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class PutBlockListItem - { - /// - /// Initializes a new instance of the class. - /// - /// The block ID. - /// One of the enumeration values that specifies in which block lists to search for the block. - public PutBlockListItem(string id, BlockSearchMode searchMode) - { - this.Id = id; - this.SearchMode = searchMode; - } - - /// - /// Gets the block ID. - /// - /// The block ID. - public string Id { get; private set; } - - /// - /// Gets a value that indicates which block lists to search for the block. - /// - /// One of the enumeration values that specifies in which block lists to search for the block. - public BlockSearchMode SearchMode { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SequenceNumberAction.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SequenceNumberAction.cs deleted file mode 100644 index bdb0dc2ad8a8d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SequenceNumberAction.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - /// - /// Describes actions that can be performed on a page blob sequence number. - /// - public enum SequenceNumberAction - { - /// - /// Sets the sequence number to be the higher of the value included with the request and the value currently stored for the blob. - /// - Max, - - /// - /// Sets the sequence number to the value included with the request. - /// - Update, - - /// - /// Increments the value of the sequence number by 1. - /// - Increment, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPermissions.cs deleted file mode 100644 index e9d55beb7c47e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPermissions.cs +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - - /// - /// Specifies the set of possible permissions for a shared access policy. - /// - [Flags] - public enum SharedAccessBlobPermissions - { - /// - /// No shared access granted. - /// - None = 0x0, - - /// - /// Read access granted. - /// - Read = 0x1, - - /// - /// Write access granted. - /// - Write = 0x2, - - /// - /// Delete access granted for blobs. - /// - Delete = 0x4, - - /// - /// List access granted. - /// - List = 0x8 - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicies.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicies.cs deleted file mode 100644 index eed93cbf241b4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicies.cs +++ /dev/null @@ -1,234 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents the collection of shared access policies defined for a container. - /// - [SuppressMessage( - "Microsoft.Naming", - "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Public APIs should not expose base collection types.")] - public sealed class SharedAccessBlobPolicies : IDictionary - { - private Dictionary policies = - new Dictionary(); - - /// - /// Adds the specified key and value to the collection of shared access policies. - /// - /// The key of the value to add. - /// The value to add the collection of shared access policies. - public void Add(string key, SharedAccessBlobPolicy value) - { - this.policies.Add(key, value); - } - - /// - /// Determines whether the collection of shared access policies contains the specified key. - /// - /// The key to locate in the collection of shared access policies. - /// true if the collection of shared access policies contains an element with the specified key; otherwise, false. - public bool ContainsKey(string key) - { - return this.policies.ContainsKey(key); - } - - /// - /// Gets a collection containing the keys in the shared access policies collection. - /// - /// A collection containing the keys in the of shared access policies collection. - public ICollection Keys - { - get - { - return this.policies.Keys; - } - } - - /// - /// Removes the value with the specified key from the shared access policies collection. - /// - /// The key of the item to remove. - /// true if the element is successfully found and removed; otherwise, false. This method returns false if the key is not found. - public bool Remove(string key) - { - return this.policies.Remove(key); - } - - /// - /// Gets the item associated with the specified key. - /// - /// The key of the value to get. - /// The item to get. - /// The item associated with the specified key, if the key is found; otherwise, the default value for the type. - public bool TryGetValue(string key, out SharedAccessBlobPolicy value) - { - return this.policies.TryGetValue(key, out value); - } - - /// - /// Gets a collection containing the values in the shared access policies collection. - /// - /// A collection of items in the shared access policies collection. - public ICollection Values - { - get - { - return this.policies.Values; - } - } - - /// - /// Gets or sets the item associated with the specified key. - /// - /// The key of the value to get or set. - /// The item associated with the specified key, or null if key is not in the shared access policies collection. - public SharedAccessBlobPolicy this[string key] - { - get - { - return this.policies[key]; - } - - set - { - this.policies[key] = value; - } - } - - /// - /// Adds the specified key/ value, stored in a , to the collection of shared access policies. - /// - /// The object, containing a key/ value pair, to add to the shared access policies collection. - public void Add(KeyValuePair item) - { - this.Add(item.Key, item.Value); - } - - /// - /// Removes all keys and values from the shared access collection. - /// - public void Clear() - { - this.policies.Clear(); - } - - /// - /// Determines whether the collection of shared access policies contains the key and value in the specified object. - /// - /// A object containing the key and value to search for. - /// true if the shared access policies collection contains the specified key/value; otherwise, false. - public bool Contains(KeyValuePair item) - { - SharedAccessBlobPolicy storedItem; - if (this.TryGetValue(item.Key, out storedItem)) - { - if (string.Equals( - SharedAccessBlobPolicy.PermissionsToString(item.Value.Permissions), - SharedAccessBlobPolicy.PermissionsToString(storedItem.Permissions), - StringComparison.Ordinal)) - { - return true; - } - } - - return false; - } - - /// - /// Copies each key/ value pair in the shared access policies collection to a compatible one-dimensional array, starting at the specified index of the target array. - /// - /// The one-dimensional array of objects that is the destination of the elements copied from the shared access policies collection. - /// The zero-based index in at which copying begins. - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - CommonUtility.AssertNotNull("array", array); - - foreach (KeyValuePair item in this.policies) - { - array[arrayIndex++] = item; - } - } - - /// - /// Gets the number of key/ value pairs contained in the shared access policies collection. - /// - /// The number of key/ value pairs contained in the shared access policies collection. - public int Count - { - get - { - return this.policies.Count; - } - } - - /// - /// Gets a value indicating whether the collection of shared access policies is read-only. - /// - /// true if the collection of shared access policies is read-only; otherwise, false. - public bool IsReadOnly - { - get - { - return false; - } - } - - /// - /// Removes the value, specified in the object, from the shared access policies collection. - /// - /// The object, containing a key and value, to remove from the shared access policies collection. - /// true if the item was successfully removed; otherwise, false. - public bool Remove(KeyValuePair item) - { - if (this.Contains(item)) - { - return this.Remove(item.Key); - } - else - { - return false; - } - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An of type . - public IEnumerator> GetEnumerator() - { - return this.policies.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An object that can be used to iterate through the collection of shared access policies. - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - System.Collections.IEnumerable enumerable = this.policies; - return enumerable.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicy.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicy.cs deleted file mode 100644 index a87e70409a04d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Blob/SharedAccessBlobPolicy.cs +++ /dev/null @@ -1,133 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Text; - - /// - /// Represents a shared access policy, which specifies the start time, expiry time, - /// and permissions for a shared access signature. - /// - public sealed class SharedAccessBlobPolicy - { - /// - /// Initializes a new instance of the class. - /// - public SharedAccessBlobPolicy() - { - } - - /// - /// Gets or sets the start time for a shared access signature associated with this shared access policy. - /// - /// The shared access start time. - public DateTimeOffset? SharedAccessStartTime { get; set; } - - /// - /// Gets or sets the expiry time for a shared access signature associated with this shared access policy. - /// - /// The shared access expiry time. - public DateTimeOffset? SharedAccessExpiryTime { get; set; } - - /// - /// Gets or sets the permissions for a shared access signature associated with this shared access policy. - /// - /// The permissions. - public SharedAccessBlobPermissions Permissions { get; set; } - - /// - /// Converts the permissions specified for the shared access policy to a string. - /// - /// The shared access permissions. - /// The shared access permissions in string format. - public static string PermissionsToString(SharedAccessBlobPermissions permissions) - { - // The service supports a fixed order => rwdl - StringBuilder builder = new StringBuilder(); - - if ((permissions & SharedAccessBlobPermissions.Read) == SharedAccessBlobPermissions.Read) - { - builder.Append("r"); - } - - if ((permissions & SharedAccessBlobPermissions.Write) == SharedAccessBlobPermissions.Write) - { - builder.Append("w"); - } - - if ((permissions & SharedAccessBlobPermissions.Delete) == SharedAccessBlobPermissions.Delete) - { - builder.Append("d"); - } - - if ((permissions & SharedAccessBlobPermissions.List) == SharedAccessBlobPermissions.List) - { - builder.Append("l"); - } - - return builder.ToString(); - } - - /// - /// Constructs a object from a permissions string. - /// - /// The shared access permissions in string format. - /// A set of shared access permissions. - public static SharedAccessBlobPermissions PermissionsFromString(string input) - { - CommonUtility.AssertNotNull("input", input); - - SharedAccessBlobPermissions permissions = 0; - - foreach (char c in input) - { - switch (c) - { - case 'r': - permissions |= SharedAccessBlobPermissions.Read; - break; - - case 'w': - permissions |= SharedAccessBlobPermissions.Write; - break; - - case 'd': - permissions |= SharedAccessBlobPermissions.Delete; - break; - - case 'l': - permissions |= SharedAccessBlobPermissions.List; - break; - - default: - throw new ArgumentOutOfRangeException("input"); - } - } - - // Incase we ever change none to be something other than 0 - if (permissions == 0) - { - permissions |= SharedAccessBlobPermissions.None; - } - - return permissions; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/CloudStorageAccount.cs b/microsoft-azure-api/Services/Storage/Lib/Common/CloudStorageAccount.cs deleted file mode 100644 index 52541ddb7103e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/CloudStorageAccount.cs +++ /dev/null @@ -1,1068 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Blob; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue; - using Microsoft.WindowsAzure.Storage.Table; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Linq; - using AccountSetting = System.Collections.Generic.KeyValuePair>; - - /// - /// Represents a Windows Azure Storage account. - /// - public sealed class CloudStorageAccount - { - /// - /// The FISMA compliance default value. - /// - private static bool version1MD5 = true; - - /// - /// Gets or sets a value indicating whether the FISMA MD5 setting will be used. - /// - /// false to use the FISMA MD5 setting; true to use the .NET default implementation. -#if WINDOWS_PHONE - internal -#else - public -#endif - static bool UseV1MD5 - { - get { return version1MD5; } - set { version1MD5 = value; } - } - - /// - /// The setting name for using the development storage. - /// - internal const string UseDevelopmentStorageSettingString = "UseDevelopmentStorage"; - - /// - /// The setting name for specifying a development storage proxy Uri. - /// - internal const string DevelopmentStorageProxyUriSettingString = "DevelopmentStorageProxyUri"; - - /// - /// The setting name for using the default storage endpoints with the specified protocol. - /// - internal const string DefaultEndpointsProtocolSettingString = "DefaultEndpointsProtocol"; - - /// - /// The setting name for the account name. - /// - internal const string AccountNameSettingString = "AccountName"; - - /// - /// The setting name for the account key name. - /// - internal const string AccountKeyNameSettingString = "AccountKeyName"; - - /// - /// The setting name for the account key. - /// - internal const string AccountKeySettingString = "AccountKey"; - - /// - /// The setting name for a custom blob storage endpoint. - /// - internal const string BlobEndpointSettingString = "BlobEndpoint"; - - /// - /// The setting name for a custom queue endpoint. - /// - internal const string QueueEndpointSettingString = "QueueEndpoint"; - - /// - /// The setting name for a custom table storage endpoint. - /// - internal const string TableEndpointSettingString = "TableEndpoint"; - - /// - /// The setting name for a custom storage endpoint suffix. - /// - internal const string EndpointSuffixSettingString = "EndpointSuffix"; - - /// - /// The setting name for a shared access key. - /// - internal const string SharedAccessSignatureSettingString = "SharedAccessSignature"; - - /// - /// The default account name for the development storage. - /// - private const string DevstoreAccountName = "devstoreaccount1"; - - /// - /// The default account key for the development storage. - /// - private const string DevstoreAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="; - - /// - /// The credentials string used to test for the development storage credentials. - /// - private const string DevstoreCredentialInString = - CloudStorageAccount.AccountNameSettingString + "=" + DevstoreAccountName + ";" + - CloudStorageAccount.AccountKeySettingString + "=" + DevstoreAccountKey; - - /// - /// The default storage service hostname suffix. - /// - private const string DefaultEndpointSuffix = "core.windows.net"; - - /// - /// The default blob storage DNS hostname prefix. - /// - private const string DefaultBlobHostnamePrefix = "blob"; - - /// - /// The root queue DNS name prefix. - /// - private const string DefaultQueueHostnamePrefix = "queue"; - - /// - /// The root table storage DNS name prefix. - /// - private const string DefaultTableHostnamePrefix = "table"; - - /// - /// Validator for the UseDevelopmentStorage setting. Must be "true". - /// - private static readonly AccountSetting UseDevelopmentStorageSetting = Setting(UseDevelopmentStorageSettingString, "true"); - - /// - /// Validator for the DevelopmentStorageProxyUri setting. Must be a valid Uri. - /// - private static readonly AccountSetting DevelopmentStorageProxyUriSetting = Setting(DevelopmentStorageProxyUriSettingString, IsValidUri); - - /// - /// Validator for the DefaultEndpointsProtocol setting. Must be either "http" or "https". - /// - private static readonly AccountSetting DefaultEndpointsProtocolSetting = Setting(DefaultEndpointsProtocolSettingString, "http", "https"); - - /// - /// Validator for the AccountName setting. No restrictions. - /// - private static readonly AccountSetting AccountNameSetting = Setting(AccountNameSettingString); - - /// - /// Validator for the AccountKey setting. No restrictions. - /// - private static readonly AccountSetting AccountKeyNameSetting = Setting(AccountKeyNameSettingString); - - /// - /// Validator for the AccountKey setting. Must be a valid base64 string. - /// - private static readonly AccountSetting AccountKeySetting = Setting(AccountKeySettingString, IsValidBase64String); - - /// - /// Validator for the BlobEndpoint setting. Must be a valid Uri. - /// - private static readonly AccountSetting BlobEndpointSetting = Setting(BlobEndpointSettingString, IsValidUri); - - /// - /// Validator for the QueueEndpoint setting. Must be a valid Uri. - /// - private static readonly AccountSetting QueueEndpointSetting = Setting(QueueEndpointSettingString, IsValidUri); - - /// - /// Validator for the TableEndpoint setting. Must be a valid Uri. - /// - private static readonly AccountSetting TableEndpointSetting = Setting(TableEndpointSettingString, IsValidUri); - - /// - /// Validator for the EndpointSuffix setting. Must be a valid Uri. - /// - private static readonly AccountSetting EndpointSuffixSetting = Setting(EndpointSuffixSettingString, IsValidDomain); - - /// - /// Validator for the SharedAccessSignature setting. No restrictions. - /// - private static readonly AccountSetting SharedAccessSignatureSetting = Setting(SharedAccessSignatureSettingString); - - /// - /// Singleton instance for the development storage account. - /// - private static CloudStorageAccount devStoreAccount; - - /// - /// Initializes a new instance of the class using the specified - /// account credentials and service endpoints. - /// - /// The account credentials. - /// The Blob service endpoint. - /// The Queue service endpoint. - /// The Table service endpoint. - public CloudStorageAccount(StorageCredentials storageCredentials, Uri blobEndpoint, Uri queueEndpoint, Uri tableEndpoint) - { - this.Credentials = storageCredentials; - this.BlobEndpoint = blobEndpoint; - this.QueueEndpoint = queueEndpoint; - this.TableEndpoint = tableEndpoint; - this.DefaultEndpoints = false; - } - - /// - /// Initializes a new instance of the class using the specified - /// account credentials and the default service endpoints. - /// - /// An object of type that - /// specifies the account name and account key for the storage account. - /// True to use HTTPS to connect to storage service endpoints; otherwise, false. - public CloudStorageAccount(StorageCredentials storageCredentials, bool useHttps) - : this(storageCredentials, null /* endpointSuffix */, useHttps) - { - } - - /// - /// Initializes a new instance of the class using the specified - /// account credentials and the default service endpoints. - /// - /// An object of type that - /// specifies the account name and account key for the storage account. - /// The DNS endpoint suffix for all storage services, e.g. "core.windows.net". - /// True to use HTTPS to connect to storage service endpoints; otherwise, false. - public CloudStorageAccount(StorageCredentials storageCredentials, string endpointSuffix, bool useHttps) - { - CommonUtility.AssertNotNull("storageCredentials", storageCredentials); - - string protocol = useHttps ? "https" : "http"; - this.BlobEndpoint = new Uri(ConstructBlobEndpoint(protocol, storageCredentials.AccountName, endpointSuffix)); - this.QueueEndpoint = new Uri(ConstructQueueEndpoint(protocol, storageCredentials.AccountName, endpointSuffix)); - this.TableEndpoint = new Uri(ConstructTableEndpoint(protocol, storageCredentials.AccountName, endpointSuffix)); - this.Credentials = storageCredentials; - this.EndpointSuffix = endpointSuffix; - this.DefaultEndpoints = true; - } - - /// - /// Gets a object that references the development storage account. - /// - /// A reference to the development storage account. - public static CloudStorageAccount DevelopmentStorageAccount - { - get - { - if (devStoreAccount == null) - { - devStoreAccount = GetDevelopmentStorageAccount(null); - } - - return devStoreAccount; - } - } - - /// - /// Indicates whether this account is a development storage account. - /// - private bool IsDevStoreAccount { get; set; } - - /// - /// The storage service hostname suffix set by the user, if any. - /// - private string EndpointSuffix { get; set; } - - /// - /// The connection string parsed into settings. - /// - private IDictionary Settings { get; set; } - - /// - /// True if the user used a constructor that auto-generates endpoints. - /// - private bool DefaultEndpoints { get; set; } - - /// - /// Gets the endpoint for the Blob service, as configured for the storage account. - /// - /// The Blob service endpoint. - public Uri BlobEndpoint { get; private set; } - - /// - /// Gets the endpoint for the Queue service, as configured for the storage account. - /// - /// The Queue service endpoint. - public Uri QueueEndpoint { get; private set; } - - /// - /// Gets the endpoint for the Table service, as configured for the storage account. - /// - /// The Table service endpoint. - public Uri TableEndpoint { get; private set; } - - /// - /// Gets the credentials used to create this object. - /// - /// The credentials used to create the object. - public StorageCredentials Credentials { get; private set; } - - /// - /// Parses a connection string and returns a created - /// from the connection string. - /// - /// A valid connection string. - /// Thrown if is null or empty. - /// Thrown if is not a valid connection string. - /// Thrown if cannot be parsed. - /// A object constructed from the values provided in the connection string. - public static CloudStorageAccount Parse(string connectionString) - { - CloudStorageAccount ret; - - if (string.IsNullOrEmpty(connectionString)) - { - throw new ArgumentNullException("connectionString"); - } - - if (ParseImpl(connectionString, out ret, err => { throw new FormatException(err); })) - { - return ret; - } - - throw new ArgumentException(SR.ParseError); - } - - /// - /// Indicates whether a connection string can be parsed to return a object. - /// - /// The connection string to parse. - /// A object to hold the instance returned if - /// the connection string can be parsed. - /// true if the connection string was successfully parsed; otherwise, false. - public static bool TryParse(string connectionString, out CloudStorageAccount account) - { - if (string.IsNullOrEmpty(connectionString)) - { - account = null; - return false; - } - - try - { - return ParseImpl(connectionString, out account, err => { }); - } - catch (Exception) - { - account = null; - return false; - } - } - - /// - /// Creates the Table service client. - /// - /// A client object that specifies the Table service endpoint. - public CloudTableClient CreateCloudTableClient() - { - if (this.TableEndpoint == null) - { - throw new InvalidOperationException(SR.TableEndPointNotConfigured); - } - - if (this.Credentials == null) - { - throw new InvalidOperationException(SR.MissingCredentials); - } - - return new CloudTableClient(this.TableEndpoint, this.Credentials); - } - - /// - /// Creates the Queue service client. - /// - /// A client object that specifies the Queue service endpoint. - public CloudQueueClient CreateCloudQueueClient() - { - if (this.QueueEndpoint == null) - { - throw new InvalidOperationException(SR.QueueEndPointNotConfigured); - } - - if (this.Credentials == null) - { - throw new InvalidOperationException(SR.MissingCredentials); - } - - return new CloudQueueClient(this.QueueEndpoint, this.Credentials); - } - - /// - /// Creates the Blob service client. - /// - /// A client object that specifies the Blob service endpoint. - public CloudBlobClient CreateCloudBlobClient() - { - if (this.BlobEndpoint == null) - { - throw new InvalidOperationException(SR.BlobEndPointNotConfigured); - } - - if (this.Credentials == null) - { - throw new InvalidOperationException(SR.MissingCredentials); - } - - return new CloudBlobClient(this.BlobEndpoint, this.Credentials); - } - - /// - /// Returns a connection string for this storage account, without sensitive data. - /// - /// A connection string. - public override string ToString() - { - return this.ToString(false); - } - - /// - /// Returns a connection string for the storage account, optionally with sensitive data. - /// - /// True to include sensitive data in the string; otherwise, false. - /// A connection string. - public string ToString(bool exportSecrets) - { - if (this.Settings == null) - { - this.Settings = new Dictionary(); - - if (this.DefaultEndpoints) - { - this.Settings.Add(DefaultEndpointsProtocolSettingString, this.BlobEndpoint.Scheme); - - if (this.EndpointSuffix != null) - { - this.Settings.Add(EndpointSuffixSettingString, this.EndpointSuffix); - } - } - else - { - if (this.BlobEndpoint != null) - { - this.Settings.Add(BlobEndpointSettingString, this.BlobEndpoint.ToString()); - } - - if (this.QueueEndpoint != null) - { - this.Settings.Add(QueueEndpointSettingString, this.QueueEndpoint.ToString()); - } - - if (this.TableEndpoint != null) - { - this.Settings.Add(TableEndpointSettingString, this.TableEndpoint.ToString()); - } - } - } - - List listOfSettings = this.Settings.Select(pair => string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Key, pair.Value)).ToList(); - - if (this.Credentials != null && !this.IsDevStoreAccount) - { - listOfSettings.Add(this.Credentials.ToString(exportSecrets)); - } - - return string.Join(";", listOfSettings); - } - - /// - /// Returns a with development storage credentials using the specified proxy Uri. - /// - /// The proxy endpoint to use. - /// The new . - private static CloudStorageAccount GetDevelopmentStorageAccount(Uri proxyUri) - { - UriBuilder builder = proxyUri != null ? - new UriBuilder(proxyUri.Scheme, proxyUri.Host) : - new UriBuilder("http", "127.0.0.1"); - - builder.Path = DevstoreAccountName; - - builder.Port = 10000; - Uri blobEndpoint = builder.Uri; - - builder.Port = 10001; - Uri queueEndpoint = builder.Uri; - - builder.Port = 10002; - Uri tableEndpoint = builder.Uri; - - StorageCredentials credentials = new StorageCredentials(DevstoreAccountName, DevstoreAccountKey); - CloudStorageAccount account = new CloudStorageAccount(credentials, blobEndpoint, queueEndpoint, tableEndpoint); - - account.Settings = new Dictionary(); - account.Settings.Add(UseDevelopmentStorageSettingString, "true"); - if (proxyUri != null) - { - account.Settings.Add(DevelopmentStorageProxyUriSettingString, proxyUri.ToString()); - } - - account.IsDevStoreAccount = true; - - return account; - } - - /// - /// Internal implementation of Parse/TryParse. - /// - /// The string to parse. - /// The to return. - /// A callback for reporting errors. - /// If true, the parse was successful. Otherwise, false. - internal static bool ParseImpl(string connectionString, out CloudStorageAccount accountInformation, Action error) - { - IDictionary settings = ParseStringIntoSettings(connectionString, error); - - // malformed settings string - if (settings == null) - { - accountInformation = null; - - return false; - } - - // devstore case - if (MatchesSpecification( - settings, - AllRequired(UseDevelopmentStorageSetting), - Optional(DevelopmentStorageProxyUriSetting))) - { - string proxyUri = null; - if (settings.TryGetValue(DevelopmentStorageProxyUriSettingString, out proxyUri)) - { - accountInformation = GetDevelopmentStorageAccount(new Uri(proxyUri)); - } - else - { - accountInformation = DevelopmentStorageAccount; - } - - accountInformation.Settings = ValidCredentials(settings); - return true; - } - - // automatic case - if (MatchesSpecification( - settings, - AllRequired(DefaultEndpointsProtocolSetting, AccountNameSetting, AccountKeySetting), - Optional(BlobEndpointSetting, QueueEndpointSetting, TableEndpointSetting, AccountKeyNameSetting, EndpointSuffixSetting))) - { - string blobEndpoint = null; - settings.TryGetValue(BlobEndpointSettingString, out blobEndpoint); - - string queueEndpoint = null; - settings.TryGetValue(QueueEndpointSettingString, out queueEndpoint); - - string tableEndpoint = null; - settings.TryGetValue(TableEndpointSettingString, out tableEndpoint); - - accountInformation = new CloudStorageAccount( - GetCredentials(settings), - new Uri(blobEndpoint ?? ConstructBlobEndpoint(settings)), - new Uri(queueEndpoint ?? ConstructQueueEndpoint(settings)), - new Uri(tableEndpoint ?? ConstructTableEndpoint(settings))); - - string endpointSuffix = null; - if (settings.TryGetValue(EndpointSuffixSettingString, out endpointSuffix)) - { - accountInformation.EndpointSuffix = endpointSuffix; - } - - accountInformation.Settings = ValidCredentials(settings); - return true; - } - - // explicit case - if (MatchesSpecification( - settings, - AtLeastOne(BlobEndpointSetting, QueueEndpointSetting, TableEndpointSetting), - ValidCredentials)) - { - Uri blobUri = !settings.ContainsKey(BlobEndpointSettingString) || settings[BlobEndpointSettingString] == null ? null : new Uri(settings[BlobEndpointSettingString]); - Uri queueUri = !settings.ContainsKey(QueueEndpointSettingString) || settings[QueueEndpointSettingString] == null ? null : new Uri(settings[QueueEndpointSettingString]); - Uri tableUri = !settings.ContainsKey(TableEndpointSettingString) || settings[TableEndpointSettingString] == null ? null : new Uri(settings[TableEndpointSettingString]); - - accountInformation = new CloudStorageAccount(GetCredentials(settings), blobUri, queueUri, tableUri); - - accountInformation.Settings = ValidCredentials(settings); - return true; - } - - // not valid - accountInformation = null; - - error("No valid combination of account information found."); - - return false; - } - - /// - /// Tokenizes input and stores name value pairs. - /// - /// The string to parse. - /// Error reporting delegate. - /// Tokenized collection. - private static IDictionary ParseStringIntoSettings(string connectionString, Action error) - { - IDictionary settings = new Dictionary(); - string[] splitted = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); - - foreach (string nameValue in splitted) - { - string[] splittedNameValue = nameValue.Split(new char[] { '=' }, 2); - - if (splittedNameValue.Length != 2) - { - error("Settings must be of the form \"name=value\"."); - return null; - } - - if (settings.ContainsKey(splittedNameValue[0])) - { - error(string.Format(CultureInfo.InvariantCulture, "Duplicate setting '{0}' found.", splittedNameValue[0])); - return null; - } - - settings.Add(splittedNameValue[0], splittedNameValue[1]); - } - - return settings; - } - - /// - /// Encapsulates a validation rule for an enumeration based account setting. - /// - /// The name of the setting. - /// A list of valid values for the setting. - /// An representing the enumeration constraint. - private static AccountSetting Setting(string name, params string[] validValues) - { - return new AccountSetting( - name, - (settingValue) => - { - if (validValues.Length == 0) - { - return true; - } - - return validValues.Contains(settingValue); - }); - } - - /// - /// Encapsulates a validation rule using a func. - /// - /// The name of the setting. - /// A func that determines if the value is valid. - /// An representing the constraint. - private static AccountSetting Setting(string name, Func isValid) - { - return new AccountSetting(name, isValid); - } - - /// - /// Determines whether the specified setting value is a valid base64 string. - /// - /// The setting value. - /// true if the specified setting value is a valid base64 string; otherwise, false. - private static bool IsValidBase64String(string settingValue) - { - try - { - Convert.FromBase64String(settingValue); - - return true; - } - catch (FormatException) - { - return false; - } - } - - /// - /// Validation function that validates Uris. - /// - /// Value to validate. - /// true if the specified setting value is a valid Uri; otherwise, false. - private static bool IsValidUri(string settingValue) - { - return Uri.IsWellFormedUriString(settingValue, UriKind.Absolute); - } - - /// - /// Validation function that validates a domain name. - /// - /// Value to validate. - /// true if the specified setting value is a valid domain; otherwise, false. - private static bool IsValidDomain(string settingValue) - { - return Uri.CheckHostName(settingValue).Equals(UriHostNameType.Dns); - } - - /// - /// Settings filter that requires all specified settings be present and valid. - /// - /// A list of settings that must be present. - /// The remaining settings or null if the filter's requirement is not satisfied. - private static Func, IDictionary> AllRequired(params AccountSetting[] requiredSettings) - { - return (settings) => - { - IDictionary result = new Dictionary(settings); - - foreach (AccountSetting requirement in requiredSettings) - { - string value; - if (result.TryGetValue(requirement.Key, out value) && requirement.Value(value)) - { - result.Remove(requirement.Key); - } - else - { - return null; - } - } - - return result; - }; - } - - /// - /// Settings filter that removes optional values. - /// - /// A list of settings that are optional. - /// The remaining settings or null if the filter's requirement is not satisfied. - private static Func, IDictionary> Optional(params AccountSetting[] optionalSettings) - { - return (settings) => - { - IDictionary result = new Dictionary(settings); - - foreach (AccountSetting requirement in optionalSettings) - { - string value; - if (result.TryGetValue(requirement.Key, out value) && requirement.Value(value)) - { - result.Remove(requirement.Key); - } - } - - return result; - }; - } - - /// - /// Settings filter that ensures that at least one setting is present. - /// - /// A list of settings of which one must be present. - /// The remaining settings or null if the filter's requirement is not satisfied. - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed.")] - private static Func, IDictionary> AtLeastOne(params AccountSetting[] atLeastOneSettings) - { - return (settings) => - { - IDictionary result = new Dictionary(settings); - bool foundOne = false; - - foreach (AccountSetting requirement in atLeastOneSettings) - { - string value; - if (result.TryGetValue(requirement.Key, out value) && requirement.Value(value)) - { - result.Remove(requirement.Key); - foundOne = true; - } - } - - return foundOne ? result : null; - }; - } - - /// - /// Settings filter that ensures that a valid combination of credentials is present. - /// - /// The remaining settings or null if the filter's requirement is not satisfied. - private static IDictionary ValidCredentials(IDictionary settings) - { - string accountName; - string accountKey; - string accountKeyName; - string sharedAccessSignature; - IDictionary result = new Dictionary(settings); - - if (settings.TryGetValue(AccountNameSettingString, out accountName) && - !AccountNameSetting.Value(accountName)) - { - return null; - } - - if (settings.TryGetValue(AccountKeySettingString, out accountKey) && - !AccountKeySetting.Value(accountKey)) - { - return null; - } - - if (settings.TryGetValue(AccountKeyNameSettingString, out accountKeyName) && - !AccountKeyNameSetting.Value(accountKeyName)) - { - return null; - } - - if (settings.TryGetValue(SharedAccessSignatureSettingString, out sharedAccessSignature) && - !SharedAccessSignatureSetting.Value(sharedAccessSignature)) - { - return null; - } - - result.Remove(AccountNameSettingString); - result.Remove(AccountKeySettingString); - result.Remove(AccountKeyNameSettingString); - result.Remove(SharedAccessSignatureSettingString); - - // AccountAndKey - if (accountName != null && accountKey != null && sharedAccessSignature == null) - { - return result; - } - - // SharedAccessSignature - if (accountName == null && accountKey == null && accountKeyName == null && sharedAccessSignature != null) - { - return result; - } - - // Anonymous - if (accountName == null && accountKey == null && accountKeyName == null && sharedAccessSignature == null) - { - return result; - } - - return null; - } - - /// - /// Tests to see if a given list of settings matches a set of filters exactly. - /// - /// The settings to check. - /// A list of filters to check. - /// - /// If any filter returns null, false. - /// If there are any settings left over after all filters are processed, false. - /// Otherwise true. - /// - private static bool MatchesSpecification( - IDictionary settings, - params Func, IDictionary>[] constraints) - { - foreach (Func, IDictionary> constraint in constraints) - { - IDictionary remainingSettings = constraint(settings); - - if (remainingSettings == null) - { - return false; - } - else - { - settings = remainingSettings; - } - } - - if (settings.Count == 0) - { - return true; - } - - return false; - } - - /// - /// Gets a StorageCredentials object corresponding to whatever credentials are supplied in the given settings. - /// - /// The settings to check. - /// The StorageCredentials object specified in the settings. - private static StorageCredentials GetCredentials(IDictionary settings) - { - string accountName; - string accountKey; - string accountKeyName; - string sharedAccessSignature; - - settings.TryGetValue(AccountNameSettingString, out accountName); - settings.TryGetValue(AccountKeySettingString, out accountKey); - settings.TryGetValue(AccountKeyNameSettingString, out accountKeyName); - settings.TryGetValue(SharedAccessSignatureSettingString, out sharedAccessSignature); - - if (accountName != null && accountKey != null && sharedAccessSignature == null) - { - return new StorageCredentials(accountName, accountKey, accountKeyName); - } - - if (accountName == null && accountKey == null && accountKeyName == null && sharedAccessSignature != null) - { - return new StorageCredentials(sharedAccessSignature); - } - - return null; - } - - /// - /// Gets the default blob endpoint using specified settings. - /// - /// The settings to use. - /// The default blob endpoint. - private static string ConstructBlobEndpoint(IDictionary settings) - { - return ConstructBlobEndpoint( - settings[DefaultEndpointsProtocolSettingString], - settings[AccountNameSettingString], - settings.ContainsKey(EndpointSuffixSettingString) ? settings[EndpointSuffixSettingString] : null); - } - - /// - /// Gets the default blob endpoint using the specified protocol and account name. - /// - /// The protocol to use. - /// The name of the storage account. - /// The Endpoint DNS suffix; use null for default. - /// The default blob endpoint. - private static string ConstructBlobEndpoint(string scheme, string accountName, string endpointSuffix) - { - if (string.IsNullOrEmpty(scheme)) - { - throw new ArgumentNullException("scheme"); - } - - if (string.IsNullOrEmpty(accountName)) - { - throw new ArgumentNullException("accountName"); - } - - if (string.IsNullOrEmpty(endpointSuffix)) - { - endpointSuffix = DefaultEndpointSuffix; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0}://{1}.{2}.{3}/", - scheme, - accountName, - DefaultBlobHostnamePrefix, - endpointSuffix); - } - - /// - /// Gets the default queue endpoint using the specified settings. - /// - /// The settings. - /// The default queue endpoint. - private static string ConstructQueueEndpoint(IDictionary settings) - { - return ConstructQueueEndpoint( - settings[DefaultEndpointsProtocolSettingString], - settings[AccountNameSettingString], - settings.ContainsKey(EndpointSuffixSettingString) ? settings[EndpointSuffixSettingString] : null); - } - - /// - /// Gets the default queue endpoint using the specified protocol and account name. - /// - /// The protocol to use. - /// The name of the storage account. - /// The Endpoint DNS suffix; use null for default. - /// The default queue endpoint. - private static string ConstructQueueEndpoint(string scheme, string accountName, string endpointSuffix) - { - if (string.IsNullOrEmpty(scheme)) - { - throw new ArgumentNullException("scheme"); - } - - if (string.IsNullOrEmpty(accountName)) - { - throw new ArgumentNullException("accountName"); - } - - if (string.IsNullOrEmpty(endpointSuffix)) - { - endpointSuffix = DefaultEndpointSuffix; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0}://{1}.{2}.{3}/", - scheme, - accountName, - DefaultQueueHostnamePrefix, - endpointSuffix); - } - - /// - /// Gets the default table endpoint using the specified settings. - /// - /// The settings. - /// The default table endpoint. - private static string ConstructTableEndpoint(IDictionary settings) - { - return ConstructTableEndpoint( - settings[DefaultEndpointsProtocolSettingString], - settings[AccountNameSettingString], - settings.ContainsKey(EndpointSuffixSettingString) ? settings[EndpointSuffixSettingString] : null); - } - - /// - /// Gets the default table endpoint using the specified protocol and account name. - /// - /// The protocol to use. - /// The name of the storage account. - /// The Endpoint DNS suffix; use null for default. - /// The default table endpoint. - private static string ConstructTableEndpoint(string scheme, string accountName, string endpointSuffix) - { - if (string.IsNullOrEmpty(scheme)) - { - throw new ArgumentNullException("scheme"); - } - - if (string.IsNullOrEmpty(accountName)) - { - throw new ArgumentNullException("accountName"); - } - - if (string.IsNullOrEmpty(endpointSuffix)) - { - endpointSuffix = DefaultEndpointSuffix; - } - - return string.Format( - CultureInfo.InvariantCulture, - "{0}://{1}.{2}.{3}/", - scheme, - accountName, - DefaultTableHostnamePrefix, - endpointSuffix); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Auth/SharedAccessSignatureHelper.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Auth/SharedAccessSignatureHelper.cs deleted file mode 100644 index ebb1e9bd9e75c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Auth/SharedAccessSignatureHelper.cs +++ /dev/null @@ -1,609 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Blob; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Contains helper methods for implementing shared access signatures. - /// - internal static class SharedAccessSignatureHelper - { - /// - /// Get the complete query builder for creating the Shared Access Signature query. - /// - /// The shared access policy to hash. - /// An optional identifier for the policy. - /// Either "b" for blobs or "c" for containers. - /// The signature to use. - /// The name of the key used to create the signature, or null if the key is implicit. - /// The finished query builder. - internal static UriQueryBuilder GetSharedAccessSignatureImpl( - SharedAccessBlobPolicy policy, - string accessPolicyIdentifier, - string resourceType, - string signature, - string accountKeyName) - { - CommonUtility.AssertNotNullOrEmpty("resourceType", resourceType); - CommonUtility.AssertNotNull("signature", signature); - - if (policy == null) - { - return GetSharedAccessSignatureImpl( - null /* policy.Permissions */, - null /* policy.SharedAccessStartTime */, - null /* policy.SharedAccessExpiryTime */, - null /* startPatitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPatitionKey (table only) */, - null /* endRowKey (table only) */, - accessPolicyIdentifier, - resourceType, - null /* tableName (table only) */, - signature, - accountKeyName); - } - - string permissions = SharedAccessBlobPolicy.PermissionsToString(policy.Permissions); - if (string.IsNullOrEmpty(permissions)) - { - permissions = null; - } - - return GetSharedAccessSignatureImpl( - permissions, - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - accessPolicyIdentifier, - resourceType, - null /* tableName (table only) */, - signature, - accountKeyName); - } - - /// - /// Get the complete query builder for creating the Shared Access Signature query. - /// - /// The shared access policy to hash. - /// An optional identifier for the policy. - /// The signature to use. - /// The name of the key used to create the signature, or null if the key is implicit. - /// The finished query builder. - internal static UriQueryBuilder GetSharedAccessSignatureImpl( - SharedAccessQueuePolicy policy, - string accessPolicyIdentifier, - string signature, - string accountKeyName) - { - CommonUtility.AssertNotNull("signature", signature); - - if (policy == null) - { - return GetSharedAccessSignatureImpl( - null /* permissions*/, - null /* policy.SharedAccessStartTime*/, - null /* policy.SharedAccessExpiryTime*/, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - accessPolicyIdentifier, - null /* resourceType (blob only) */, - null /* tableName (table only) */, - signature, - accountKeyName); - } - - string permissions = SharedAccessQueuePolicy.PermissionsToString(policy.Permissions); - if (string.IsNullOrEmpty(permissions)) - { - permissions = null; - } - - return GetSharedAccessSignatureImpl( - permissions, - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - accessPolicyIdentifier, - null /* resourceType (blob only) */, - null /* tableName (table only) */, - signature, - accountKeyName); - } - - /// - /// Get the complete query builder for creating the Shared Access Signature query. - /// - /// The shared access policy to hash. - /// The name of the table associated with this shared access signature. - /// An optional identifier for the policy. - /// The start partition key, or null. - /// The start row key, or null. - /// The end partition key, or null. - /// The end row key, or null. - /// The signature to use. - /// The name of the key used to create the signature, or null if the key is implicit. - /// The finished query builder. - internal static UriQueryBuilder GetSharedAccessSignatureImpl( - SharedAccessTablePolicy policy, - string tableName, - string accessPolicyIdentifier, - string startPartitionKey, - string startRowKey, - string endPartitionKey, - string endRowKey, - string signature, - string accountKeyName) - { - CommonUtility.AssertNotNull("signature", signature); - - if (policy == null) - { - return GetSharedAccessSignatureImpl( - null /* policy.Permissions */, - null /* policy.SharedAccessStartTime */, - null /* policy.SharedAccessExpiryTime */, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - accessPolicyIdentifier, - null /* resourceType (blob only) */, - tableName, - signature, - accountKeyName); - } - - string permissions = SharedAccessTablePolicy.PermissionsToString(policy.Permissions); - if (string.IsNullOrEmpty(permissions)) - { - permissions = null; - } - - return GetSharedAccessSignatureImpl( - permissions, - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - accessPolicyIdentifier, - null /* resourceType (blob only) */, - tableName, - signature, - accountKeyName); - } - - /// - /// Converts the specified value to either a string representation or . - /// - /// The value to convert. - /// A string representing the specified value. - internal static string GetDateTimeOrEmpty(DateTimeOffset? value) - { - string result = GetDateTimeOrNull(value) ?? string.Empty; - return result; - } - - /// - /// Converts the specified value to either a string representation or null. - /// - /// The value to convert. - /// A string representing the specified value. - internal static string GetDateTimeOrNull(DateTimeOffset? value) - { - string result = value != null ? value.Value.UtcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture) : null; - return result; - } - - /// - /// Escapes and adds the specified name/value pair to the query builder if it is not null. - /// - /// The builder to add the value to. - /// The name of the pair. - /// The value to be escaped. - internal static void AddEscapedIfNotNull(UriQueryBuilder builder, string name, string value) - { - if (value != null) - { - builder.Add(name, value); - } - } - - /// - /// Parses the query. - /// - /// The query parameters. - /// A boolean that represents whether SignedResource is part of Sas or not. True for blobs, False for Queues and Tables. - [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "ToLower(CultureInfo) is not present in RT and ToLowerInvariant() also violates FxCop")] - internal static StorageCredentials ParseQuery(IDictionary queryParameters, bool mandatorySignedResource) - { - string signature = null; - string signedStart = null; - string signedExpiry = null; - string signedResource = null; - string sigendPermissions = null; - string signedIdentifier = null; - string signedVersion = null; - string tableName = null; - - bool sasParameterFound = false; - - foreach (KeyValuePair parameter in queryParameters) - { - switch (parameter.Key.ToLower()) - { - case Constants.QueryConstants.SignedStart: - signedStart = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SignedExpiry: - signedExpiry = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SignedPermissions: - sigendPermissions = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SignedResource: - signedResource = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SignedIdentifier: - signedIdentifier = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.Signature: - signature = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SignedVersion: - signedVersion = parameter.Value; - sasParameterFound = true; - break; - - case Constants.QueryConstants.SasTableName: - tableName = parameter.Value; - sasParameterFound = true; - break; - - default: - break; - } - } - - if (sasParameterFound) - { - if (signature == null || (mandatorySignedResource && signedResource == null)) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.MissingMandatoryParametersForSAS); - throw new ArgumentException(errorMessage); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedStart, signedStart); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedExpiry, signedExpiry); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedPermissions, sigendPermissions); - if (signedResource != null) - { - builder.Add(Constants.QueryConstants.SignedResource, signedResource); - } - - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedIdentifier, signedIdentifier); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedVersion, signedVersion); - AddEscapedIfNotNull(builder, Constants.QueryConstants.Signature, signature); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SasTableName, tableName); - - return new StorageCredentials(builder.ToString()); - } - - return null; - } - - /// - /// Get the complete query builder for creating the Shared Access Signature query. - /// - /// The permissions string for the resource, or null. - /// The start time, or null. - /// The expiration time, or null. - /// The start partition key, or null. - /// The start row key, or null. - /// The end partition key, or null. - /// The end row key, or null. - /// An optional identifier for the policy. - /// Either "b" for blobs or "c" for containers, or null if neither. - /// The name of the table this signature is associated with, - /// or null if not using table SAS. - /// The signature to use. - /// The name of the key used to create the signature, or null if the key is implicit. - /// The finished query builder. - private static UriQueryBuilder GetSharedAccessSignatureImpl( - string permissions, - DateTimeOffset? startTime, - DateTimeOffset? expiryTime, - string startPartitionKey, - string startRowKey, - string endPartitionKey, - string endRowKey, - string accessPolicyIdentifier, - string resourceType, - string tableName, - string signature, - string accountKeyName) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedVersion, Constants.HeaderConstants.TargetStorageVersion); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedStart, GetDateTimeOrNull(startTime)); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedExpiry, GetDateTimeOrNull(expiryTime)); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedResource, resourceType); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SasTableName, tableName); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedPermissions, permissions); - AddEscapedIfNotNull(builder, Constants.QueryConstants.StartPartitionKey, startPartitionKey); - AddEscapedIfNotNull(builder, Constants.QueryConstants.StartRowKey, startRowKey); - AddEscapedIfNotNull(builder, Constants.QueryConstants.EndPartitionKey, endPartitionKey); - AddEscapedIfNotNull(builder, Constants.QueryConstants.EndRowKey, endRowKey); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedIdentifier, accessPolicyIdentifier); - AddEscapedIfNotNull(builder, Constants.QueryConstants.SignedKey, accountKeyName); - AddEscapedIfNotNull(builder, Constants.QueryConstants.Signature, signature); - - return builder; - } - - /// - /// Get the signature hash embedded inside the Shared Access Signature. - /// - /// The shared access policy to hash. - /// An optional identifier for the policy. - /// The canonical resource string, unescaped. - /// The key value retrieved as an atomic operation used for signing. - /// The signed hash. - internal static string GetSharedAccessSignatureHashImpl( - SharedAccessBlobPolicy policy, - string accessPolicyIdentifier, - string resourceName, - byte[] keyValue) - { - if (policy == null) - { - return GetSharedAccessSignatureHashImpl( - null /* policy.Permissions */, - null /* policy.SharedAccessStartTime */, - null /* policy.SharedAccessExpiryTime */, - null /* startPatitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPatitionKey (table only) */, - null /* endRowKey (table only) */, - false /* not using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - - return GetSharedAccessSignatureHashImpl( - SharedAccessBlobPolicy.PermissionsToString(policy.Permissions), - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - false /* not using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - - /// - /// Get the signature hash embedded inside the Shared Access Signature. - /// - /// The shared access policy to hash. - /// An optional identifier for the policy. - /// The canonical resource string, unescaped. - /// The key value retrieved as an atomic operation used for signing. - /// The signed hash. - internal static string GetSharedAccessSignatureHashImpl( - SharedAccessQueuePolicy policy, - string accessPolicyIdentifier, - string resourceName, - byte[] keyValue) - { - if (policy == null) - { - return GetSharedAccessSignatureHashImpl( - null /*SharedAccessQueuePolicy.Permissions */, - null /*policy.SharedAccessStartTime*/, - null /*policy.SharedAccessExpiryTime*/, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - false /* not using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - else - { - return GetSharedAccessSignatureHashImpl( - SharedAccessQueuePolicy.PermissionsToString(policy.Permissions), - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - null /* startPartitionKey (table only) */, - null /* startRowKey (table only) */, - null /* endPartitionKey (table only) */, - null /* endRowKey (table only) */, - false /* not using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - } - - /// - /// Get the signature hash embedded inside the Shared Access Signature. - /// - /// The shared access policy to hash. - /// An optional identifier for the policy. - /// The start partition key, or null. - /// The start row key, or null. - /// The end partition key, or null. - /// The end row key, or null. - /// The canonical resource string, unescaped. - /// The key value retrieved as an atomic operation used for signing. - /// The signed hash. - internal static string GetSharedAccessSignatureHashImpl( - SharedAccessTablePolicy policy, - string accessPolicyIdentifier, - string startPartitionKey, - string startRowKey, - string endPartitionKey, - string endRowKey, - string resourceName, - byte[] keyValue) - { - if (policy == null) - { - return GetSharedAccessSignatureHashImpl( - null /* policy.Permissions */, - null /* policy.SharedAccessStartTime */, - null /* policy.SharedAccessExpiryTime */, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - true /* using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - - return GetSharedAccessSignatureHashImpl( - SharedAccessTablePolicy.PermissionsToString(policy.Permissions), - policy.SharedAccessStartTime, - policy.SharedAccessExpiryTime, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - true /* using table SAS */, - accessPolicyIdentifier, - resourceName, - keyValue); - } - - /// - /// Get the signature hash embedded inside the Shared Access Signature. - /// - /// The permissions string for the resource, or null. - /// The start time, or null. - /// The expiration time, or null. - /// The start partition key, or null. - /// The start row key, or null. - /// The end partition key, or null. - /// The end row key, or null. - /// Whether to use the table string-to-sign. - /// An optional identifier for the policy. - /// The canonical resource string, unescaped. - /// The key value retrieved as an atomic operation used for signing. - /// The signed hash. - [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.WindowsAzure.Storage.Core.Util.CryptoUtility.ComputeHmac256(System.Byte[],System.String)", Justification = "Reviewed")] - private static string GetSharedAccessSignatureHashImpl( - string permissions, - DateTimeOffset? startTime, - DateTimeOffset? expiryTime, - string startPartitionKey, - string startRowKey, - string endPartitionKey, - string endRowKey, - bool useTableSas, - string accessPolicyIdentifier, - string resourceName, - byte[] keyValue) - { - CommonUtility.AssertNotNullOrEmpty("resourceName", resourceName); - CommonUtility.AssertNotNull("keyValue", keyValue); - - //// StringToSign = signedpermissions + "\n" + - //// signedstart + "\n" + - //// signedexpiry + "\n" + - //// canonicalizedresource + "\n" + - //// signedidentifier + "\n" + - //// signedversion - //// - //// TableStringToSign = StringToSign + "\n" + - //// startpk + "\n" + - //// startrk + "\n" + - //// endpk + "\n" + - //// endrk - //// - //// HMAC-SHA256(UTF8.Encode(StringToSign)) - - string stringToSign = string.Format( - CultureInfo.InvariantCulture, - "{0}\n{1}\n{2}\n{3}\n{4}\n{5}", - permissions, - GetDateTimeOrEmpty(startTime), - GetDateTimeOrEmpty(expiryTime), - resourceName, - accessPolicyIdentifier, - Constants.HeaderConstants.TargetStorageVersion); - - if (useTableSas) - { - stringToSign = string.Format( - CultureInfo.InvariantCulture, - "{0}\n{1}\n{2}\n{3}\n{4}", - stringToSign, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey); - } - - string signature = CryptoUtility.ComputeHmac256(keyValue, stringToSign); - - return signature; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/CanonicalizedString.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/CanonicalizedString.cs deleted file mode 100644 index 7b0a42fb5c7c0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/CanonicalizedString.cs +++ /dev/null @@ -1,73 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using System.Text; - - /// - /// Represents a canonicalized string used in authenticating a request against the azure service. - /// - internal class CanonicalizedString - { - private const int DefaultCapacity = 300; - private const char ElementDelimiter = '\n'; - - /// - /// Stores the internal that holds the canonicalized string. - /// - private readonly StringBuilder canonicalizedString; - - /// - /// Initializes a new instance of the class. - /// - /// The first canonicalized element to start the string with. - public CanonicalizedString(string initialElement) - : this(initialElement, CanonicalizedString.DefaultCapacity) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The first canonicalized element to start the string with. - /// The starting size of the string. - public CanonicalizedString(string initialElement, int capacity) - { - this.canonicalizedString = new StringBuilder(initialElement, capacity); - } - - /// - /// Append additional canonicalized element to the string. - /// - /// An additional canonicalized element to append to the string. - public void AppendCanonicalizedElement(string element) - { - this.canonicalizedString.Append(CanonicalizedString.ElementDelimiter); - this.canonicalizedString.Append(element); - } - - /// - /// Converts the value of this instance to a string. - /// - /// A string whose value is the same as this instance. - public override string ToString() - { - return this.canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutionState.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutionState.cs deleted file mode 100644 index f29fa8caf7168..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutionState.cs +++ /dev/null @@ -1,293 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Globalization; - using System.IO; - using System.Threading; - -#if WINDOWS_RT - using System.Net.Http; -#else - using System.Net; -#endif - - // This class encapsulates a StorageCommand and stores state about its execution. - // Note conceptually there is some overlap between ExecutionState and operationContext, however the - // operationContext is the user visible object and the ExecutionState is an internal object used to coordinate execution. -#if WINDOWS_RT - internal class ExecutionState : IDisposable -#else - // If we are exposing APM then derive this class from the StorageCommandAsyncResult - internal class ExecutionState : StorageCommandAsyncResult -#endif - { - public ExecutionState(StorageCommandBase cmd, IRetryPolicy policy, OperationContext operationContext) - { - this.Cmd = cmd; - this.RetryPolicy = policy != null ? policy.CreateInstance() : new NoRetry(); - this.OperationContext = operationContext ?? new OperationContext(); - -#if WINDOWS_RT - if (this.OperationContext.StartTime == DateTimeOffset.MinValue) - { - this.OperationContext.StartTime = DateTimeOffset.Now; - } -#else - if (this.OperationContext.StartTime == DateTime.MinValue) - { - this.OperationContext.StartTime = DateTime.Now; - } -#endif - } - -#if WINDOWS_DESKTOP - public ExecutionState(StorageCommandBase cmd, IRetryPolicy policy, OperationContext operationContext, AsyncCallback callback, object asyncState) - : base(callback, asyncState) - { - this.Cmd = cmd; - this.RetryPolicy = policy != null ? policy.CreateInstance() : new NoRetry(); - this.OperationContext = operationContext ?? new OperationContext(); - - if (this.OperationContext.StartTime == DateTime.MinValue) - { - this.OperationContext.StartTime = DateTime.Now; - } - } -#endif - - internal void Init() - { - this.Req = null; - this.resp = null; - -#if !WINDOWS_RT - this.ReqTimedOut = false; - this.CancelDelegate = null; -#endif - } - -#if WINDOWS_RT - public void Dispose() - { - this.CheckDisposeSendStream(); - } -#else - protected override void Dispose(bool disposing) - { - if (disposing) - { - Timer backoffTimer = this.BackoffTimer; - if (backoffTimer != null) - { - this.BackoffTimer = null; - backoffTimer.Dispose(); - } - - this.CheckDisposeSendStream(); - } - - base.Dispose(disposing); - } - - internal Timer BackoffTimer { get; set; } -#endif - - internal OperationContext OperationContext { get; set; } - - internal DateTime? OperationExpiryTime - { - get { return this.Cmd.OperationExpiryTime; } - } - - internal IRetryPolicy RetryPolicy { get; set; } - - internal StorageCommandBase Cmd { get; set; } - - internal RESTCommand RestCMD - { - get - { - return this.Cmd as RESTCommand; - } - } - - internal ExecutorOperation CurrentOperation { get; set; } - - internal TimeSpan RemainingTimeout - { - get - { - if (!this.OperationExpiryTime.HasValue || this.OperationExpiryTime.Value.Equals(DateTime.MaxValue)) - { - // User did not specify a timeout, so we will set the request timeout to avoid - // waiting for the response infinitely - return Constants.DefaultClientSideTimeout; - } - else - { - TimeSpan potentialTimeout = this.OperationExpiryTime.Value - DateTime.Now; - - if (potentialTimeout <= TimeSpan.Zero) - { - throw Exceptions.GenerateTimeoutException(this.Cmd.CurrentResult, null); - } - - return potentialTimeout; - } - } - } - - private int retryCount = 0; - - internal int RetryCount - { - get { return this.retryCount; } - set { this.retryCount = value; } - } - - internal Stream ReqStream { get; set; } - - private volatile Exception exceptionRef = null; - - internal Exception ExceptionRef - { - get - { - return this.exceptionRef; - } - - set - { - this.exceptionRef = value; - if (this.Cmd != null && this.Cmd.CurrentResult != null) - { - this.Cmd.CurrentResult.Exception = value; - } - } - } - - internal T Result { get; set; } - - private object timeoutLockerObj = new object(); - private bool reqTimedOut = false; - - internal bool ReqTimedOut - { - get - { - lock (this.timeoutLockerObj) - { - return this.reqTimedOut; - } - } - - set - { - lock (this.timeoutLockerObj) - { - this.reqTimedOut = value; - } - } - } - - private void CheckDisposeSendStream() - { - RESTCommand cmd = this.RestCMD; - - if ((cmd != null) && (cmd.StreamToDispose != null)) - { - cmd.StreamToDispose.Dispose(); - cmd.StreamToDispose = null; - } - } - -#if WINDOWS_RT - internal HttpClient Client { get; set; } - - internal HttpRequestMessage Req { get; set; } - - private HttpResponseMessage resp = null; - - internal HttpResponseMessage Resp - { - get - { - return this.resp; - } - - set - { - this.resp = value; - - if (value != null) - { - this.Cmd.CurrentResult.ServiceRequestID = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(this.resp.Headers, Constants.HeaderConstants.RequestIdHeader); - this.Cmd.CurrentResult.ContentMd5 = this.resp.Content.Headers.ContentMD5 != null ? Convert.ToBase64String(this.resp.Content.Headers.ContentMD5) : null; - this.Cmd.CurrentResult.Etag = this.resp.Headers.ETag != null ? this.resp.Headers.ETag.ToString() : null; - this.Cmd.CurrentResult.RequestDate = this.resp.Headers.Date.HasValue ? this.resp.Headers.Date.Value.UtcDateTime.ToString("R", CultureInfo.InvariantCulture) : null; - this.Cmd.CurrentResult.HttpStatusMessage = this.resp.ReasonPhrase; - this.Cmd.CurrentResult.HttpStatusCode = (int)this.resp.StatusCode; - } - } - } -#else - internal HttpWebRequest Req { get; set; } - - private HttpWebResponse resp = null; - - internal HttpWebResponse Resp - { - get - { - return this.resp; - } - - set - { - this.resp = value; - - if (this.resp != null) - { - if (value.Headers != null) - { -#if WINDOWS_DESKTOP - this.Cmd.CurrentResult.ServiceRequestID = HttpWebUtility.TryGetHeader(this.resp, Constants.HeaderConstants.RequestIdHeader, null); - this.Cmd.CurrentResult.ContentMd5 = HttpWebUtility.TryGetHeader(this.resp, "Content-MD5", null); - string tempDate = HttpWebUtility.TryGetHeader(this.resp, "Date", null); - this.Cmd.CurrentResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate; - this.Cmd.CurrentResult.Etag = this.resp.Headers[HttpResponseHeader.ETag]; -#endif - } - - this.Cmd.CurrentResult.HttpStatusMessage = this.Cmd.CurrentResult.HttpStatusMessage ?? this.resp.StatusDescription; - - if (this.Cmd.CurrentResult.HttpStatusCode == -1) - { - this.Cmd.CurrentResult.HttpStatusCode = (int)this.resp.StatusCode; - } - } - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorBase.cs deleted file mode 100644 index 0756cbf62e260..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorBase.cs +++ /dev/null @@ -1,118 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - - internal abstract class ExecutorBase - { - protected static void ApplyUserHeaders(ExecutionState executionState) - { - if (!string.IsNullOrEmpty(executionState.OperationContext.ClientRequestID)) - { - executionState.Req.Headers.Add(Constants.HeaderConstants.ClientRequestIdHeader, executionState.OperationContext.ClientRequestID); - } - - if (executionState.OperationContext.UserHeaders != null && executionState.OperationContext.UserHeaders.Count > 0) - { - foreach (string key in executionState.OperationContext.UserHeaders.Keys) - { - executionState.Req.Headers.Add(key, executionState.OperationContext.UserHeaders[key]); - } - } - } - - protected static void StartRequestAttempt(ExecutionState executionState) - { - executionState.Cmd.CurrentResult = new RequestResult(); - - // Need to clear this explicitly for retries - executionState.ExceptionRef = null; - - lock (executionState.OperationContext.RequestResults) - { - executionState.OperationContext.RequestResults.Add(executionState.Cmd.CurrentResult); - } - - executionState.Cmd.CurrentResult.StartTime = DateTime.Now; - } - - protected static void FinishRequestAttempt(ExecutionState executionState) - { - executionState.Cmd.CurrentResult.EndTime = DateTime.Now; - executionState.OperationContext.EndTime = DateTime.Now; - } - - protected static void FireSendingRequest(ExecutionState executionState) - { - RequestEventArgs args = new RequestEventArgs(executionState.Cmd.CurrentResult); -#if WINDOWS_RT - args.RequestUri = executionState.Req.RequestUri; -#else - args.Request = executionState.Req; -#endif - executionState.OperationContext.FireSendingRequest(args); - } - - protected static void FireResponseReceived(ExecutionState executionState) - { - RequestEventArgs args = new RequestEventArgs(executionState.Cmd.CurrentResult); -#if WINDOWS_RT - args.RequestUri = executionState.Req.RequestUri; -#else - args.Request = executionState.Req; - args.Response = executionState.Resp; -#endif - executionState.OperationContext.FireResponseReceived(args); - } - - protected static bool CheckTimeout(ExecutionState executionState, bool throwOnTimeout) - { - if (executionState.ReqTimedOut || (executionState.OperationExpiryTime.HasValue && executionState.Cmd.CurrentResult.StartTime.CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - executionState.ReqTimedOut = true; - - StorageException storageEx = Exceptions.GenerateTimeoutException(executionState.Cmd.CurrentResult, null); - executionState.ExceptionRef = storageEx; - - if (throwOnTimeout) - { - throw executionState.ExceptionRef; - } - - return true; - } - - return false; - } - -#if WINDOWS_DESKTOP - protected static bool CheckCancellation(ExecutionState executionState) - { - if (executionState.CancelRequested) - { - executionState.ExceptionRef = Exceptions.GenerateCancellationException(executionState.Cmd.CurrentResult, null); - } - - return executionState.CancelRequested; - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorOperation.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorOperation.cs deleted file mode 100644 index da93bb5c13b82..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/ExecutorOperation.cs +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - internal enum ExecutorOperation - { - NotStarted = 0, - BeginOperation, - BeginGetRequestStream, - EndGetRequestStream, - BeginUploadRequest, - EndUploadRequest, - BeginGetResponse, - EndGetResponse, - PreProcess, - GetResponseStream, - BeginDownloadResponse, - EndDownloadResponse, - PostProcess, - EndOperation, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/RESTCommand.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/RESTCommand.cs deleted file mode 100644 index 4d4780cbd4db0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/RESTCommand.cs +++ /dev/null @@ -1,117 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Auth; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - -#if WINDOWS_RT -using System.Net.Http; -using System.Threading.Tasks; -#else - using System.Net; -#endif - - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - internal class RESTCommand : StorageCommandBase - { - #region Ctors - public RESTCommand(StorageCredentials credentials, Uri uri) - : this(credentials, uri, null) - { - } - - public RESTCommand(StorageCredentials credentials, Uri uri, UriQueryBuilder builder) - { - this.Uri = credentials.TransformUri(uri); - this.Builder = builder; - } - #endregion - - // Reference to hold stream from webresponse - public Stream ResponseStream = null; - - // Stream to potentially copy response into - public Stream DestinationStream = null; - - // if true, the inStream will be set before processresponse is called. - public bool RetrieveResponseStream = false; - - // if true the executor will calculate the md5 on retrieved data - public bool CalculateMd5ForResponseStream = false; - - public Stream StreamToDispose { get; set; } - -#if WINDOWS_RT - public Func, OperationContext, HttpClient> BuildClient; - - public Func, OperationContext, HttpContent> BuildContent; - - public Func, HttpContent, OperationContext, HttpRequestMessage> BuildRequest; - - // Pre-Stream Retrival func (i.e. if 409 no stream is retrieved), in some cases this method will return directly - public Func, HttpResponseMessage, Exception, OperationContext, T> PreProcessResponse; - - // Post-Stream Retrieval Func ( if retreiveStream is true after ProcessResponse, the stream is retrieved and then PostProcess is called - public Func, HttpResponseMessage, OperationContext, Task> PostProcessResponse; -#else - // Stream to send to server - private Stream sendStream = null; - - public Stream SendStream - { - get - { - return this.sendStream; - } - - set - { - MultiBufferMemoryStream tempStream = value as MultiBufferMemoryStream; - if (tempStream != null) - { - this.StreamToDispose = tempStream; - } - - this.sendStream = value; - } - } - - // Length of data to send to server from stream. - public long? SendStreamLength = null; - - // Func to construct the request - public Func BuildRequestDelegate = null; - - // Delegate to Set custom headers - public Action SetHeaders = null; - - // Delegate to Sign headers - note this is important that it doesnt have a type dependency on StorageCredentials here - // due to build issues and WinRT restrictions. - public Action SignRequest = null; - - // Pre-Stream Retrival func (i.e. if 409 no stream is retrieved), in some cases this method will return directly - public Func, HttpWebResponse, Exception, OperationContext, T> PreProcessResponse = null; - - // Post-Stream Retrieval Func ( if retreiveStream is true after ProcessResponse, the stream is retrieved and then PostProcess is called - public Func, HttpWebResponse, OperationContext, T> PostProcessResponse = null; -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/StorageCommandBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/StorageCommandBase.cs deleted file mode 100644 index 0ccd88669e86a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Executor/StorageCommandBase.cs +++ /dev/null @@ -1,124 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Blob; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue; - using Microsoft.WindowsAzure.Storage.Table; - using System; - using System.Diagnostics.CodeAnalysis; - -#if WINDOWS_RT - using System.Net.Http; -#endif - - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - internal abstract class StorageCommandBase - { - public Uri Uri; - - // The UriQueryBuilder used to create the request - public UriQueryBuilder Builder; - - // Server Timeout to send - public int? ServerTimeoutInSeconds = null; - - // Max client timeout, enforced over entire operation on client side - internal DateTime? OperationExpiryTime = null; - - // State- different than async state, this is used for ops to communicate state between invocations, i.e. bytes downloaded etc - internal object OperationState = null; - - // Used to keep track of Md5 / Length of a stream as it is being copied - private volatile StreamDescriptor streamCopyState = null; - - internal StreamDescriptor StreamCopyState - { - get { return this.streamCopyState; } - set { this.streamCopyState = value; } - } - - private volatile RequestResult currentResult = null; - - internal RequestResult CurrentResult - { - get { return this.currentResult; } - set { this.currentResult = value; } - } - -#if WINDOWS_RT - public HttpClientHandler Handler = null; -#endif - - // Delegate that will be executed in the event of an Exception after signing - public Action, Exception, OperationContext> RecoveryAction = null; - - internal void ApplyRequestOptions(BlobRequestOptions options) - { - if (options.ServerTimeout.HasValue) - { - this.ServerTimeoutInSeconds = (int)options.ServerTimeout.Value.TotalSeconds; - } - - if (options.OperationExpiryTime.HasValue) - { - this.OperationExpiryTime = options.OperationExpiryTime; - } - else if (options.MaximumExecutionTime.HasValue) - { - this.OperationExpiryTime = DateTime.Now + options.MaximumExecutionTime.Value; - } - } - - internal void ApplyRequestOptions(TableRequestOptions options) - { - if (options.ServerTimeout.HasValue) - { - this.ServerTimeoutInSeconds = (int)options.ServerTimeout.Value.TotalSeconds; - } - - if (options.OperationExpiryTime.HasValue) - { - this.OperationExpiryTime = options.OperationExpiryTime; - } - else if (options.MaximumExecutionTime.HasValue) - { - this.OperationExpiryTime = DateTime.Now + options.MaximumExecutionTime.Value; - } - } - - internal void ApplyRequestOptions(QueueRequestOptions options) - { - if (options.ServerTimeout.HasValue) - { - this.ServerTimeoutInSeconds = (int)options.ServerTimeout.Value.TotalSeconds; - } - - if (options.OperationExpiryTime.HasValue) - { - this.OperationExpiryTime = options.OperationExpiryTime; - } - else if (options.MaximumExecutionTime.HasValue) - { - this.OperationExpiryTime = DateTime.Now + options.MaximumExecutionTime.Value; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Logger.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Logger.Common.cs deleted file mode 100644 index 8425704cd233e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Logger.Common.cs +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using System.Globalization; - - internal static partial class Logger - { - private const string TraceFormat = "{0}: {1}"; - - /// - /// Creates a well-formatted log entry so that logs can be easily parsed - /// - /// An object that represents the context for the current operation. - /// A composite format string. - /// An object array that contains zero or more objects to format. - /// Log entry that contains common log prefix and a copy of format in which the format items have been replaced by the string representation of the corresponding objects in args. - private static string FormatLine(OperationContext operationContext, string format, object[] args) - { - return string.Format( - CultureInfo.InvariantCulture, - Logger.TraceFormat, - (operationContext == null) ? "*" : operationContext.ClientRequestID, - (args == null) ? format : string.Format(CultureInfo.InvariantCulture, format, args).Replace('\n', '.')); - } - - /// - /// Determines if the current operation context allows for a specific level of log entry. - /// - /// Level of the log entry. - /// An object that represents the context for the current operation. - /// true if the entry should be logged; otherwise false. - private static bool ShouldLog(LogLevel level, OperationContext operationContext) - { - return (operationContext == null) || (level <= operationContext.LogLevel); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/MultiBufferMemoryStream.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/MultiBufferMemoryStream.cs deleted file mode 100644 index d8e0d2cf56520..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/MultiBufferMemoryStream.cs +++ /dev/null @@ -1,770 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - -#if WINDOWS_RT - using System.Threading; - using System.Threading.Tasks; -#endif - - /// - /// This class provides MemoryStream-like behavior but uses a list of buffers rather than a single buffer. - /// - internal class MultiBufferMemoryStream : Stream - { - private class CopyState - { - public Stream Destination { get; set; } - - public DateTime? ExpiryTime { get; set; } - } - - /// - /// The default small buffer size. - /// - private const int DefaultSmallBufferSize = (int)(64 * Constants.KB); - - /// - /// The size of each buffer. - /// - private readonly int bufferSize; - - /// - /// The underlying buffer blocks for the stream. - /// - private List bufferBlocks = new List(); - - /// - /// The currently used length. - /// - private long length; - - /// - /// The total capacity of the stream. - /// - private long capacity; - - /// - /// The current position. - /// - private long position; - - /// - /// A reference to the IBufferManager for the stream to use to acquire and return buffers. - /// - private IBufferManager bufferManager; - - /// - /// Initializes a new instance of the MultiBufferMemoryStream class with provided IBufferManager. - /// - /// A reference to the IBufferManager for the stream to use to acquire and return buffers. May be null. - /// The Buffer size to use for each block, default is 64 KB. Note this parameter is disregarded when a IBufferManager is specified. - public MultiBufferMemoryStream(IBufferManager bufferManager, int bufferSize = MultiBufferMemoryStream.DefaultSmallBufferSize) - { - this.bufferManager = bufferManager; - - this.bufferSize = this.bufferManager == null ? bufferSize : this.bufferManager.GetDefaultBufferSize(); - - if (bufferSize <= 0) - { - throw new ArgumentOutOfRangeException("bufferSize", "Buffer size must be a positive, non-zero value"); - } - } - - /// - /// Gets a value indicating whether the current stream supports reading. - /// - /// Is true if the stream supports reading; otherwise, false. - public override bool CanRead - { - get - { - return true; - } - } - - /// - /// Gets a value indicating whether the current stream supports seeking. - /// - /// Is true if the stream supports seeking; otherwise, false. - public override bool CanSeek - { - get - { - return true; - } - } - - /// - /// Gets a value indicating whether the current stream supports writing. - /// - /// Is true if the stream supports writing; otherwise, false. - public override bool CanWrite - { - get - { - return true; - } - } - - /// - /// Gets the currently written length. - /// - public override long Length - { - get - { - return this.length; - } - } - - /// - /// Represents the current position in the stream. - /// - /// Thrown if position is outside the stream size - public override long Position - { - get - { - return this.position; - } - - set - { - this.Seek(value, SeekOrigin.Begin); - } - } - - /// - /// Reads a block of bytes from the current stream and writes the data to a buffer. - /// - /// When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source. - /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. - /// The maximum number of bytes to be read. - /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the end of the stream has been reached. - public override int Read(byte[] buffer, int offset, int count) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - return this.ReadInternal(buffer, offset, count); - } - -#if WINDOWS_DESKTOP - /// - /// Begins an asynchronous read operation. - /// - /// When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source. - /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. - /// The maximum number of bytes to be read. - /// An optional asynchronous callback, to be called when the read is complete. - /// A user-provided object that distinguishes this particular asynchronous read request from other requests. - /// An IAsyncResult that represents the asynchronous read, which could still be pending. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - try - { - result.Result = this.Read(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - - return result; - } - - /// - /// Waits for the pending asynchronous read to complete. - /// - /// The reference to the pending asynchronous request to finish. - /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the end of the stream has been reached. - public override int EndRead(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - return result.Result; - } -#endif - -#if WINDOWS_RT - /// - /// Asynchronously reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. - /// - /// The buffer to write the data into. - /// The byte offset in buffer at which to begin writing data from the stream. - /// The maximum number of bytes to read. - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous read operation. - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return Task.FromResult(this.Read(buffer, offset, count)); - } -#endif - - /// - /// Sets the position within the current stream. - /// - /// A byte offset relative to the origin parameter. - /// A value of type System.IO.SeekOrigin indicating the reference point used to obtain the new position. - /// The new position within the current stream. - /// Thrown if is invalid for SeekOrigin. - public override long Seek(long offset, SeekOrigin origin) - { - long newPosition; - switch (origin) - { - case SeekOrigin.Begin: - newPosition = offset; - break; - - case SeekOrigin.Current: - newPosition = this.position + offset; - break; - - case SeekOrigin.End: - newPosition = this.Length + offset; - break; - - default: - CommonUtility.ArgumentOutOfRange("origin", origin); - throw new ArgumentOutOfRangeException("origin"); - } - - CommonUtility.AssertInBounds("offset", newPosition, 0, this.Length); - - this.position = newPosition; - return this.position; - } - - /// - /// Sets the length of the current stream to the specified value. (pre-allocating the bufferBlocks). - /// - /// The desired length of the current stream in bytes. - /// If the is negative. - public override void SetLength(long value) - { - this.Reserve(value); - this.length = value; - } - - /// - /// Writes a block of bytes to the current stream using data read from a buffer. - /// - /// The buffer to write data from. - /// The zero-based byte offset in buffer at which to begin copying bytes to the current stream. - /// The number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - // Grow the buffer if more space is needed - if (this.position + count > this.capacity) - { - this.Reserve(this.position + count); - } - - this.WriteInternal(buffer, offset, count); - - // Adjust the length to be the max of currently written data. - this.length = Math.Max(this.length, this.position); - } - -#if WINDOWS_DESKTOP - /// - /// Begins an asynchronous write operation. - /// - /// The buffer to write data from. - /// The zero-based byte offset in buffer at which to begin copying bytes to the current stream. - /// The number of bytes to write. - /// An optional asynchronous callback, to be called when the write is complete. - /// A user-provided object that distinguishes this particular asynchronous write request from other requests. - /// An IAsyncResult that represents the asynchronous write, which could still be pending. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads")] - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - try - { - this.Write(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - - return result; - } - - /// - /// Ends an asynchronous write operation. - /// - /// The reference to the pending asynchronous request to finish. - public override void EndWrite(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - } -#endif - -#if WINDOWS_RT - /// - /// Asynchronously writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. - /// - /// The buffer to write data from. - /// The zero-based byte offset in buffer from which to begin copying bytes to the stream. - /// The maximum number of bytes to write. - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous write operation. - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - this.Write(buffer, offset, count); - return Task.FromResult(true); - } -#endif - /// - /// Does not perform any operation as it's an in-memory stream. - /// - public override void Flush() - { - } - -#if WINDOWS_RT - /// - /// Does not perform any operation as it's an in-memory stream. - /// - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous flush operation. - public override Task FlushAsync(CancellationToken cancellationToken) - { - return Task.FromResult(true); - } -#endif - -#if WINDOWS_DESKTOP - /// - /// Reads the bytes from the current stream and writes them to another stream. However, this method eliminates copying the data into a temporary buffer by directly writing to the destination stream. - /// - /// The stream to which the contents of the current stream will be copied. - /// DateTime indicating the expiry time. - public void FastCopyTo(Stream destination, DateTime? expiryTime) - { - CommonUtility.AssertNotNull("destination", destination); - - // Maximum amount you can read is from current spot to the end. - long leftToRead = this.Length - this.Position; - - try - { - while (leftToRead != 0) - { - if (expiryTime.HasValue && DateTime.Now.CompareTo(expiryTime.Value) > 0) - { - throw new TimeoutException(); - } - - ArraySegment currentBlock = this.GetCurrentBlock(); - - // Copy the block - int blockReadLength = (int)Math.Min(leftToRead, currentBlock.Count); - destination.Write(currentBlock.Array, currentBlock.Offset, blockReadLength); - - this.AdvancePosition(ref leftToRead, blockReadLength); - } - } - catch (Exception) - { - if (expiryTime.HasValue && DateTime.Now.CompareTo(expiryTime.Value) > 0) - { - throw new TimeoutException(); - } - else - { - throw; - } - } - } - - /// - /// Begins an asynchronous fast-copy operation. - /// - /// The stream to which the contents of the current stream will be copied. - /// DateTime indicating the expiry time. - /// An optional asynchronous callback, to be called when the copy is complete. - /// A user-provided object that distinguishes this particular asynchronous copy request from other requests. - /// An IAsyncResult that represents the asynchronous copy, which could still be pending. - public IAsyncResult BeginFastCopyTo(Stream destination, DateTime? expiryTime, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("destination", destination); - - StorageAsyncResult result = new StorageAsyncResult(callback, state); - result.OperationState = new CopyState() - { - Destination = destination, - ExpiryTime = expiryTime, - }; - - this.FastCopyToInternal(result); - return result; - } - - /// - /// Initiates a write operation for the next buffer in line. - /// - /// Internal StorageAsyncResult that represents the asynchronous copy. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void FastCopyToInternal(StorageAsyncResult result) - { - CopyState copyState = (CopyState)result.OperationState; - - // Maximum amount you can read is from current spot to the end. - long leftToRead = this.Length - this.Position; - - try - { - while (leftToRead != 0) - { - if (copyState.ExpiryTime.HasValue && DateTime.Now.CompareTo(copyState.ExpiryTime.Value) > 0) - { - throw new TimeoutException(); - } - - ArraySegment currentBlock = this.GetCurrentBlock(); - - int blockReadLength = (int)Math.Min(leftToRead, currentBlock.Count); - this.AdvancePosition(ref leftToRead, blockReadLength); - - IAsyncResult asyncResult = copyState.Destination.BeginWrite(currentBlock.Array, currentBlock.Offset, blockReadLength, this.FastCopyToCallback, result); - - if (!asyncResult.CompletedSynchronously) - { - return; - } - - copyState.Destination.EndWrite(asyncResult); - } - - result.OnComplete(); - } - catch (Exception e) - { - if (copyState.ExpiryTime.HasValue && DateTime.Now.CompareTo(copyState.ExpiryTime.Value) > 0) - { - result.OnComplete(new TimeoutException()); - } - else - { - result.OnComplete(e); - } - } - } - - /// - /// Callback method to be called when the corresponding write operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void FastCopyToCallback(IAsyncResult asyncResult) - { - if (asyncResult.CompletedSynchronously) - { - return; - } - - StorageAsyncResult result = (StorageAsyncResult)asyncResult.AsyncState; - result.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously); - - CopyState copyState = (CopyState)result.OperationState; - - try - { - copyState.Destination.EndWrite(asyncResult); - this.FastCopyToInternal(result); - } - catch (Exception e) - { - if (copyState.ExpiryTime.HasValue && DateTime.Now.CompareTo(copyState.ExpiryTime.Value) > 0) - { - result.OnComplete(new TimeoutException()); - } - else - { - result.OnComplete(e); - } - } - } - - /// - /// Ends an asynchronous copy operation. - /// - /// The reference to the pending asynchronous request to finish. - public void EndFastCopyTo(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - } -#endif - -#if WINDOWS_RT - /// - /// Asynchronously reads the bytes from the current stream and writes them to another stream. However, this method eliminates copying the data into a temporary buffer by directly writing to the destination stream. - /// - /// The stream to which the contents of the current stream will be copied. - /// DateTime indicating the expiry time. - /// A task that represents the asynchronous copy operation. - public async Task FastCopyToAsync(Stream destination, DateTime? expiryTime) - { - CommonUtility.AssertNotNull("destination", destination); - - // Maximum amount you can read is from current spot to the end. - long leftToRead = this.Length - this.Position; - - try - { - while (leftToRead != 0) - { - if (expiryTime.HasValue && DateTime.Now.CompareTo(expiryTime.Value) > 0) - { - throw new TimeoutException(); - } - - ArraySegment currentBlock = this.GetCurrentBlock(); - - // Copy the block - int blockReadLength = (int)Math.Min(leftToRead, currentBlock.Count); - await destination.WriteAsync(currentBlock.Array, currentBlock.Offset, blockReadLength); - - this.AdvancePosition(ref leftToRead, blockReadLength); - } - } - catch (Exception) - { - if (expiryTime.HasValue && DateTime.Now.CompareTo(expiryTime.Value) > 0) - { - throw new TimeoutException(); - } - else - { - throw; - } - } - } -#endif - -#if !WINDOWS_PHONE - /// - /// Computes the hash value for this stream. - /// - /// String representation of the computed hash value. - public string ComputeMD5Hash() - { - using (MD5Wrapper md5 = new MD5Wrapper()) - { - // Maximum amount you can read is from current spot to the end. - long leftToRead = this.Length - this.Position; - - while (leftToRead != 0) - { - ArraySegment currentBlock = this.GetCurrentBlock(); - - // Update hash with the block - int blockReadLength = (int)Math.Min(leftToRead, currentBlock.Count); - md5.UpdateHash(currentBlock.Array, currentBlock.Offset, blockReadLength); - - this.AdvancePosition(ref leftToRead, blockReadLength); - } - - return md5.ComputeHash(); - } - } -#endif - - /// - /// Ensures that the amount of bufferBlocks is greater than or equal to the required size. - /// Does not trim the size. - /// - /// The required size. - /// If the is negative. - private void Reserve(long requiredSize) - { - if (requiredSize < 0) - { - throw new ArgumentOutOfRangeException("requiredSize", "The size must be positive"); - } - - while (requiredSize > this.capacity) - { - this.AddBlock(); - } - } - - /// - /// Adds another block to the underlying bufferBlocks. - /// - private void AddBlock() - { - byte[] newBuff = this.bufferManager == null ? new byte[this.bufferSize] : this.bufferManager.TakeBuffer(this.bufferSize); - if (newBuff.Length != this.bufferSize) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, SR.BufferManagerProvidedIncorrectLengthBuffer, this.bufferSize, newBuff.Length)); - } - - this.bufferBlocks.Add(newBuff); - this.capacity += this.bufferSize; - } - - /// - /// Copies the specified amount of data from internal buffers to the buffer and advances the position. - /// - /// An array of bytes. When this method returns, the buffer contains the specified byte array with the values - /// between offset and (offset + count - 1) replaced by the bytes read from the current source. - /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. - /// The maximum number of bytes to be read from the current stream. - /// The total number of bytes read into the buffer. This can be less than the number of bytes requested - /// if that many bytes are not currently available, or zero (0) if the end of the stream has been reached. - /// - private int ReadInternal(byte[] buffer, int offset, int count) - { - // Maximum amount you can read is from current spot to the end. - int readLength = (int)Math.Min(this.Length - this.Position, count); - int leftToRead = readLength; - - while (leftToRead != 0) - { - ArraySegment currentBlock = this.GetCurrentBlock(); - - // Copy the block - int blockReadLength = (int)Math.Min(leftToRead, currentBlock.Count); - Buffer.BlockCopy(currentBlock.Array, currentBlock.Offset, buffer, offset, blockReadLength); - - this.AdvancePosition(ref offset, ref leftToRead, blockReadLength); - } - - return readLength; - } - - /// - /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. - /// (Requires the stream to be of sufficient size for writing). - /// - /// An array of bytes. This method copies count bytes from buffer to the current stream. - /// The zero-based byte offset in buffer at which to begin copying bytes to the current stream. - /// The number of bytes to be written to the current stream. - private void WriteInternal(byte[] buffer, int offset, int count) - { - while (count != 0) - { - ArraySegment currentBlock = this.GetCurrentBlock(); - - // Copy the block - int blockWriteLength = (int)Math.Min(count, currentBlock.Count); - Buffer.BlockCopy(buffer, offset, currentBlock.Array, currentBlock.Offset, blockWriteLength); - - this.AdvancePosition(ref offset, ref count, blockWriteLength); - } - } - - /// - /// Advances the current position of the stream and adjust the offset and remainder based on the amount completed. - /// - /// The current offset in the external buffer. - /// The amount of data left to process. - /// The amount of data processed. - private void AdvancePosition(ref int offset, ref int leftToProcess, int amountProcessed) - { - // Advance the position in the stream and in the destination buffer - this.position += amountProcessed; - offset += amountProcessed; - leftToProcess -= amountProcessed; - } - - /// - /// Advances the current position of the stream and adjust the remainder based on the amount completed. - /// - /// The amount of data left to process. - /// The amount of data processed. - private void AdvancePosition(ref long leftToProcess, int amountProcessed) - { - // Advance the position in the stream and in the destination buffer - this.position += amountProcessed; - leftToProcess -= amountProcessed; - } - - /// - /// Calculate the block for the current position. - /// - private ArraySegment GetCurrentBlock() - { - // Calculate the block and position in a block - int blockID = (int)(this.position / this.bufferSize); - int blockPosition = (int)(this.position % this.bufferSize); - byte[] currentBlock = this.bufferBlocks[blockID]; - - return new ArraySegment(currentBlock, blockPosition, currentBlock.Length - blockPosition); - } - - private volatile bool disposed = false; - - protected override void Dispose(bool disposing) - { - if (!this.disposed) - { - this.disposed = true; - if (disposing) - { - if (this.bufferManager != null) - { - foreach (byte[] buff in this.bufferBlocks) - { - this.bufferManager.ReturnBuffer(buff); - } - } - - this.bufferBlocks.Clear(); - } - } - - base.Dispose(disposing); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/NullType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/NullType.cs deleted file mode 100644 index 90518fff5b10c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/NullType.cs +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - /// - /// A NullTaskReturn type. - /// - public sealed class NullType - { - /// - /// Represents a no-return from a task. - /// - internal static readonly NullType Value = new NullType(); - - /// - /// Prevents a default instance of the class from being created. - /// - private NullType() - { - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/SR.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/SR.cs deleted file mode 100644 index 829b614061121..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/SR.cs +++ /dev/null @@ -1,187 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - /// - /// Provides a standard set of errors that could be thrown from the client library. - /// - internal class SR - { - public const string ArgumentEmptyError = "The argument must not be empty string."; - public const string ArgumentOutOfRangeError = "The argument is out of range. Value passed: {0}"; - public const string ArgumentTooLargeError = "The argument '{0}' is larger than maximum of '{1}'"; - public const string ArgumentTooSmallError = "The argument '{0}' is smaller than minimum of '{1}'"; - public const string BatchWithRetreiveContainsOtherOperations = "A batch transaction with a retrieve operation cannot contain any other operations."; - public const string BinaryMessageShouldUseBase64Encoding = "EncodeMessage should be true for binary message."; - public const string BlobDataCorrupted = "Blob data corrupted (integrity check failed), Expected value is '{0}', retrieved '{1}'"; - public const string BlobEndPointNotConfigured = "No blob endpoint configured."; - public const string BlobInvalidSequenceNumber = "The sequence number may not be specified for an increment operation."; - public const string BlobStreamAlreadyCommitted = "Blob stream has already been committed once."; - public const string BlobStreamFlushPending = "Blob stream has a pending flush operation. Please call EndFlush first."; - public const string BlobStreamReadPending = "Blob stream has a pending read operation. Please call EndRead first."; - public const string BlobTypeMismatch = "Blob type of the blob reference doesn't match blob type of the blob."; - public const string BufferTooSmall = "The provided buffer is too small to fit in the blob data given the offset."; - public const string BufferManagerProvidedIncorrectLengthBuffer = "The IBufferManager provided an incorrect length buffer to the stream, Expected {0}, received {1}. Buffer length should equal the value returned by IBufferManager.GetDefaultBufferSize()."; - public const string CannotCreateSASForSnapshot = "Cannot create Shared Access Signature for snapshots. Perform the operation on the root blob instead."; - public const string CannotCreateSASSignatureForGivenCred = "Cannot create Shared Access Signature as the credentials does not have account name information. Please check that the credentials used support creating Shared Access Signature."; - public const string CannotCreateSASWithoutAccountKey = "Cannot create Shared Access Signature unless Account Key credentials are used."; - public const string CannotModifySnapshot = "Cannot perform this operation on a blob representing a snapshot."; - public const string CannotUpdateKeyWithoutAccountKeyCreds = "Cannot update key unless Account Key credentials are used."; - public const string CannotUpdateSasWithoutSasCreds = "Cannot update Shared Access Signature unless Sas credentials are used."; - public const string ConcurrentOperationsNotSupported = "Could not acquire exclusive use of the TableServiceContext, Concurrent operations are not supported."; - public const string ContentMD5NotCalculated = "The operation requires a response body but no data was copied to the destination buffer."; - public const string CopyAborted = "The copy operation has been aborted by the user."; - public const string CopyFailed = "The copy operation failed with the following error message: {0}"; - public const string CryptoFunctionFailed = "Crypto function failed with error code '{0}'"; - public const string DeleteSnapshotsNotValidError = "The option '{0}' must be 'None' to delete a specific snapshot specified by '{1}'"; - public const string EmptyBatchOperation = "Cannot execute an empty batch operation"; - public const string ETagMissingForDelete = "Delete requires an ETag (which may be the '*' wildcard)."; - public const string ETagMissingForMerge = "Merge requires an ETag (which may be the '*' wildcard)."; - public const string ETagMissingForReplace = "Replace requires an ETag (which may be the '*' wildcard)."; - public const string ExceptionOccurred = "An exception has occurred. For more information please deserialize this message via RequestResult.TranslateFromExceptionMessage."; - public const string ExtendedErrorUnavailable = "An unknown error has occurred, extended error information not available."; - public const string IncorrectNumberOfBytes = "Incorrect number of bytes received. Expected '{0}', received '{1}'"; - public const string InternalStorageError = "Unexpected internal storage client error."; - public const string InvalidAclType = "Invalid acl public access type returned '{0}'. Expected blob or container."; - public const string InvalidBlobListItem = "Invalid blob list item returned"; - public const string InvalidBlobName = "Blob name is invalid. Valid names should be 1 through 1024 characters long and should not end with a . or /"; - public const string InvalidContainerName = "Container name is invalid. Valid names start and end with a lower case letter or a number and has in between a lower case letter, number or dash with no consecutive dashes and is 3 through 63 characters long"; - public const string InvalidDirectoryName = "Directory name is invalid. Valid names should be 1 through 1024 characters long and should not end with a . or /"; - public const string InvalidLeaseStatus = "Invalid lease status in response: '{0}'"; - public const string InvalidLeaseState = "Invalid lease state in response: '{0}'"; - public const string InvalidLeaseDuration = "Invalid lease duration in response: '{0}'"; - public const string InvalidLoggingLevel = "Invalid logging operations specified."; - public const string InvalidMetricsLevel = "Invalid metrics level specified."; - public const string InvalidPageSize = "Page data must be a multiple of 512 bytes."; - public const string InvalidQueueName = "Queue name is invalid. Valid names start and end with a lower case letter or a number and has in between a lower case letter, number or dash with no consecutive dashes and is 3 through 63 characters long"; - public const string InvalidTableName = "Table name is invalid. Valid names are case insensitive, start with a letter and is followed by letters or numbers and is 3 through 63 characters long"; - public const string IQueryableExtensionObjectMustBeTableQuery = "Query must be a TableQuery"; - public const string LeaseConditionOnSource = "A lease condition cannot be specified on the source of a copy."; - public const string LeaseTimeNotReceived = "Valid lease time expected but not received from the service."; - public const string LengthNotInRange = "The length provided is out of range. The range must be between 0 and the length of the byte array."; - public const string ListSnapshotsWithDelimiterError = "Listing snapshots is only supported in flat mode (no delimiter). Consider setting the useFlatBlobListing parameter to true."; - public const string LoggingVersionNull = "The logging version is null or empty."; - public const string MD5MismatchError = "Calculated MD5 does not match existing property"; - public const string MD5NotPossible = "MD5 cannot be calculated for an existing page blob because it would require reading the existing data. Please disable StoreBlobContentMD5."; - public const string MD5NotPresentError = "MD5 does not exist. If you do not want to force validation, please disable UseTransactionalMD5."; - public const string MessageTooLarge = "Messages cannot be larger than {0} bytes."; - public const string MetricVersionNull = "The metrics version is null or empty."; - public const string MissingAccountInformationInUri = "Cannot find account information inside Uri '{0}'"; - public const string MissingContainerInformation = "Invalid blob address '{0}', missing container information"; - public const string MissingCredentials = "No credentials provided."; - public const string MissingLeaseIDChanging = "A lease ID must be specified when changing a lease."; - public const string MissingLeaseIDReleasing = "A lease ID must be specified when releasing a lease."; - public const string MissingLeaseIDRenewing = "A lease ID must be specified when renewing a lease."; - public const string MissingMandatoryParametersForSAS = "Missing mandatory parameters for valid Shared Access Signature"; - public const string MultipleCredentialsProvided = "Cannot provide credentials as part of the address and as constructor parameter. Either pass in the address or use a different constructor."; - public const string MultipleSnapshotTimesProvided = "Multiple different snapshot times provided as part of query '{0}' and as constructor parameter '{1}'."; - public const string ODataReaderNotInCompletedState = "OData Reader state expected to be Completed state. Actual state: {0}."; - public const string OperationCanceled = "Operation was canceled by user."; - public const string ParseError = "Error parsing value"; - public const string PartitionKey = "All entities in a given batch must have the same partition key."; - public const string PathStyleUriMissingAccountNameInformation = "Missing account name information inside path style uri. Path style uris should be of the form http:///"; - public const string PutBlobNeedsStoreBlobContentMD5 = "When uploading a blob in a single request, StoreBlobContentMD5 must be set to true if UseTransactionalMD5 is true, because the MD5 calculated for the transaction will be stored in the blob."; - public const string QueueEndPointNotConfigured = "No queue endpoint configured."; - public const string RelativeAddressNotPermitted = "Address '{0}' is not an absolute address. Relative addresses are not permitted in here."; - public const string ResourceConsumed = "Resource consumed"; - public const string StreamLengthError = "The length of the stream exceeds the permitted length."; - public const string StreamLengthMismatch = "Cannot specify both copyLength and maxLength."; - public const string StreamLengthShortError = "The requested number of bytes exceeds the length of the stream remaining from the specified position."; - public const string TableEndPointNotConfigured = "No table endpoint configured."; - public const string TableQueryDynamicPropertyAccess = "Accessing property dictionary of DynamicTableEntity requires a string constant for property name."; - public const string TableQueryEntityPropertyInQueryNotSupported = "Referencing {0} on EntityProperty only supported with properties dictionary exposed via DynamicTableEntity."; - public const string TableQueryFluentMethodNotAllowed = "Fluent methods may not be invoked on a Query created via CloudTable.CreateQuery()"; - public const string TableQueryMustHaveQueryProvider = "Unknown Table. The TableQuery does not have an associated CloudTable Reference. Please execute the query via the CloudTable ExecuteQuery APIs."; - public const string TableQueryTypeMustImplementITableEnitty = "TableQuery Generic Type must implement the ITableEntity Interface"; - public const string TableQueryTypeMustHaveDefaultParameterlessCtor = "TableQuery Generic Type must provide a default parameterless constructor."; - public const string TakeCountNotPositive = "Take count must be positive and greater than 0."; - public const string TimeoutExceptionMessage = "The client could not finish the operation within specified timeout."; - public const string TooManyPolicyIdentifiers = "Too many '{0}' shared access policy identifiers provided. Server does not support setting more than '{1}' on a single container, queue, or table."; - public const string TraceAbort = "Aborting pending request due to timeout."; - public const string TraceAbortError = "Could not abort pending request because of {0}."; - public const string TraceAbortRetry = "Aborting pending retry due to user request."; - public const string TraceDownload = "Downloading response body."; - public const string TraceGenericError = "Exception thrown during the operation: {0}."; - public const string TraceGetResponse = "Waiting for response."; - public const string TraceGetResponseError = "Exception thrown while waiting for response: {0}."; - public const string TraceIgnoreAttribute = "Omitting property '{0}' from serialization/de-serialization because IgnoreAttribute has been set on that property."; - public const string TraceInitRequestError = "Exception thrown while initializing request: {0}."; - public const string TraceMissingDictionaryEntry = "Omitting property '{0}' from de-serialization because there is no corresponding entry in the dictionary provided."; - public const string TraceNonPublicGetSet = "Omitting property '{0}' from serialization/de-serialization because the property's getter/setter are not public."; - public const string TracePrepareUpload = "Preparing to write request data."; - public const string TracePrepareUploadError = "Exception thrown while preparing to write request data: {0}."; - public const string TracePreProcessDone = "Response headers were processed successfully, proceeding with the rest of the operation."; - public const string TracePreProcessError = "Exception thrown while processing response: {0}."; - public const string TracePostProcess = "Processing response body."; - public const string TracePostProcessError = "Exception thrown while ending operation: {0}."; - public const string TraceResponse = "Response received. Status code = {0}, Request ID = {1}, Content-MD5 = {2}, ETag = {3}."; - public const string TraceRetry = "Retrying failed operation."; - public const string TraceRetryCheck = "Checking if the operation should be retried. Retry count = {0}, HTTP status code = {1}, Retryable exception = {2}, Exception = {3}."; - public const string TraceRetryDecisionPolicy = "Retry policy did not allow for a retry. Failing with {0}."; - public const string TraceRetryDecisionTimeout = "Operation cannot be retried because we are out of time. Failing with {0}."; - public const string TraceRetryDelay = "Operation will be retried after {0}ms."; - public const string TraceRetryError = "Exception thrown while retrying operation: {0}."; - public const string TraceStartRequestAsync = "Starting asynchronous request to {0}."; - public const string TraceStartRequestSync = "Starting synchronous request to {0}."; - public const string TraceStringToSign = "StringToSign = {0}."; - public const string TraceSuccess = "Operation completed successfully."; - public const string TraceUpload = "Writing request data."; - public const string TraceUploadError = "Exception thrown while writing request data: {0}."; - public const string UndefinedBlobType = "The blob type cannot be undefined."; - public const string UnexpectedElement = "Unexpected Element '{0}'"; - public const string UnexpectedEmptyElement = "Unexpected Empty Element '{0}'"; - public const string UnexpectedContinuationType = "Unexpected Continuation Type"; - public const string UnexpectedResponseCode = "Unexpected response code, Expected:{0}, Received:{1}"; - public const string UnexpectedResponseCodeForOperation = "Unexpected response code for operation : "; - public const string UpdateMessageVisibilityRequired = "Calls to UpdateMessage must include the Visibility flag."; - -#if WINDOWS_PHONE - public const string WindowsPhoneDoesNotSupportMD5 = "MD5 is not supported on Windows Phone"; -#endif - // Table IQueryable Exception messages - public const string ALinqCouldNotConvert = "Could not convert constant {0} expression to string."; - public const string ALinqMethodNotSupported = "The method '{0}' is not supported."; - public const string ALinqUnaryNotSupported = "The unary operator '{0}' is not supported."; - public const string ALinqBinaryNotSupported = "The binary operator '{0}' is not supported."; - public const string ALinqConstantNotSupported = "The constant for '{0}' is not supported."; - public const string ALinqTypeBinaryNotSupported = "An operation between an expression and a type is not supported."; - public const string ALinqConditionalNotSupported = "The conditional expression is not supported."; - public const string ALinqParameterNotSupported = "The parameter expression is not supported."; - public const string ALinqMemberAccessNotSupported = "The member access of '{0}' is not supported."; - public const string ALinqLambdaNotSupported = "Lambda Expressions not supported."; - public const string ALinqNewNotSupported = "New Expressions not supported."; - public const string ALinqMemberInitNotSupported = "Member Init Expressions not supported."; - public const string ALinqListInitNotSupported = "List Init Expressions not supported."; - public const string ALinqNewArrayNotSupported = "New Array Expressions not supported."; - public const string ALinqInvocationNotSupported = "Invocation Expressions not supported."; - public const string ALinqUnsupportedExpression = "The expression type {0} is not supported."; - public const string ALinqCanOnlyProjectTheLeaf = "Can only project the last entity type in the query being translated."; - public const string ALinqCantCastToUnsupportedPrimitive = "Can't cast to unsupported type '{0}'"; - public const string ALinqCantTranslateExpression = "The expression {0} is not supported."; - public const string ALinqCantNavigateWithoutKeyPredicate = "Navigation properties can only be selected from a single resource. Specify a key predicate to restrict the entity set to a single instance."; - public const string ALinqCantReferToPublicField = "Referencing public field '{0}' not supported in query option expression. Use public property instead."; - public const string ALinqCannotConstructKnownEntityTypes = "Construction of entity type instances must use object initializer with default constructor."; - public const string ALinqCannotCreateConstantEntity = "Referencing of local entity type instances not supported when projecting results."; - public const string ALinqExpressionNotSupportedInProjectionToEntity = "Initializing instances of the entity type {0} with the expression {1} is not supported."; - public const string ALinqExpressionNotSupportedInProjection = "Constructing or initializing instances of the type {0} with the expression {1} is not supported."; - public const string ALinqProjectionMemberAssignmentMismatch = "Cannot initialize an instance of entity type '{0}' because '{1}' and '{2}' do not refer to the same source entity."; - public const string ALinqPropertyNamesMustMatchInProjections = "Cannot assign the value from the {0} property to the {1} property. When projecting results into a entity type, the property names of the source type and the target type must match for the properties being projected."; - public const string ALinqQueryOptionOutOfOrder = "The {0} query option cannot be specified after the {1} query option."; - public const string ALinqQueryOptionsOnlyAllowedOnLeafNodes = "Can only specify query options (orderby, where, take, skip) after last navigation."; - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/SyncMemoryStream.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/SyncMemoryStream.cs deleted file mode 100644 index 1749a5985ddf8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/SyncMemoryStream.cs +++ /dev/null @@ -1,154 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - - /// - /// This class provides APM Read/Write overrides for memory stream to improve performance. - /// - internal class SyncMemoryStream : MemoryStream - { - /// - /// Initializes a new instance of the SyncMemoryStream class with an expandable capacity initialized to zero. - /// - public SyncMemoryStream() - : base() - { - } - - /// - /// Initializes a new non-resizable instance of the SyncMemoryStream class based on the specified byte array. - /// - /// The array of unsigned bytes from which to create the current stream. - public SyncMemoryStream(byte[] buffer) - : base(buffer) - { - } - - /// - /// Initializes a new non-resizable instance of the SyncMemoryStream class based on the specified region (index) of a byte array. - /// - /// The array of unsigned bytes from which to create the current stream. - /// The index into buffer at which the stream begins. - public SyncMemoryStream(byte[] buffer, int index) - : base(buffer, index, buffer.Length - index) - { - } - - /// - /// Initializes a new non-resizable instance of the SyncMemoryStream class based on the specified region (index) of a byte array. - /// - /// The array of unsigned bytes from which to create the current stream. - /// The index into buffer at which the stream begins. - /// The length of the stream in bytes. - public SyncMemoryStream(byte[] buffer, int index, int count) - : base(buffer, index, count) - { - } - -#if !WINDOWS_RT - /// - /// Begins an asynchronous read operation. - /// - /// When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source. - /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. - /// The maximum number of bytes to be read. - /// An optional asynchronous callback, to be called when the read is complete. - /// A user-provided object that distinguishes this particular asynchronous read request from other requests. - /// An IAsyncResult that represents the asynchronous read, which could still be pending. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - try - { - result.Result = this.Read(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - - return result; - } - - /// - /// Waits for the pending asynchronous read to complete. - /// - /// The reference to the pending asynchronous request to finish. - /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the end of the stream has been reached. - public override int EndRead(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - return result.Result; - } - - /// - /// Begins an asynchronous write operation. - /// - /// The buffer to write data from. - /// The zero-based byte offset in buffer at which to begin copying bytes to the current stream. - /// The number of bytes to write. - /// An optional asynchronous callback, to be called when the write is complete. - /// A user-provided object that distinguishes this particular asynchronous write request from other requests. - /// An IAsyncResult that represents the asynchronous write, which could still be pending. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads")] - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - try - { - this.Write(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - - return result; - } - - /// - /// Ends an asynchronous write operation. - /// - /// The reference to the pending asynchronous request to finish. - public override void EndWrite(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/UriQueryBuilder.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/UriQueryBuilder.cs deleted file mode 100644 index b249cb47428b6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/UriQueryBuilder.cs +++ /dev/null @@ -1,117 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using System; - using System.Collections.Generic; - using System.Text; - - /// - /// A convenience class for constructing URI query strings. - /// -#if WINDOWS_RT - internal -#else - public -#endif - class UriQueryBuilder - { - /// - /// Stores the query parameters. - /// - private Dictionary parameters = new Dictionary(); - - /// - /// Add the value with URI escaping. - /// - /// The query name. - /// The query value. - public void Add(string name, string value) - { - if (value != null) - { - value = Uri.EscapeDataString(value); - } - - this.parameters.Add(name, value); - } - - /// - /// Returns a containing the URI. - /// - /// - /// A containing the URI. - /// - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - bool first = true; - - foreach (KeyValuePair pair in this.parameters) - { - if (first) - { - first = false; - sb.Append("?"); - } - else - { - sb.Append("&"); - } - - sb.Append(pair.Key); - - if (pair.Value != null) - { - sb.AppendFormat("={0}", pair.Value); - } - } - - return sb.ToString(); - } - - /// - /// Adds a query parameter to a URI. - /// - /// The original URI, including any existing query parameters. - /// The URI with the new query parameter appended. - public Uri AddToUri(Uri uri) - { - // The correct way to add query parameters to a URI http://msdn.microsoft.com/en-us/library/system.uribuilder.query.aspx - string queryToAppend = this.ToString(); - - if (queryToAppend.Length > 1) - { - queryToAppend = queryToAppend.Substring(1); - } - - UriBuilder baseUri = new UriBuilder(uri); - - if (baseUri.Query != null && baseUri.Query.Length > 1) - { - baseUri.Query = baseUri.Query.Substring(1) + "&" + queryToAppend; - } - else - { - baseUri.Query = queryToAppend; - } - - return baseUri.Uri; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AsyncSemaphore.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AsyncSemaphore.Common.cs deleted file mode 100644 index 00b68ba3f7cb6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AsyncSemaphore.Common.cs +++ /dev/null @@ -1,30 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - internal partial class AsyncSemaphore - { - private int count; - - public AsyncSemaphore(int initialCount) - { - CommonUtility.AssertInBounds("initialCount", initialCount, 0, int.MaxValue); - this.count = initialCount; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AuthenticationUtility.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AuthenticationUtility.cs deleted file mode 100644 index 3f638521ac585..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/AuthenticationUtility.cs +++ /dev/null @@ -1,297 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Net; - using System.Text; -#if WINDOWS_RT - using System.Net.Http; -#endif - - internal static class AuthenticationUtility - { - private const int ExpectedResourceStringLength = 100; - private const int ExpectedHeaderNameAndValueLength = 50; - private const char HeaderNameValueSeparator = ':'; - private const char HeaderValueDelimiter = ','; - -#if WINDOWS_RT - /// - /// Gets the value of the x-ms-date or Date header. - /// - /// The request where the value is read from. - /// The value of the x-ms-date or Date header. - public static string GetPreferredDateHeaderValue(HttpRequestMessage request) - { - string microsoftDateHeaderValue = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(request.Headers, Constants.HeaderConstants.Date); - if (!string.IsNullOrEmpty(microsoftDateHeaderValue)) - { - return microsoftDateHeaderValue; - } - - return AuthenticationUtility.GetCanonicalizedHeaderValue(request.Headers.Date); - } - - /// - /// Appends the value of the Content-Length header to the specified canonicalized string. - /// - /// The canonicalized string where the value is appended. - /// The request where the value is read from. - public static void AppendCanonicalizedContentLengthHeader(CanonicalizedString canonicalizedString, HttpRequestMessage request) - { - long? contentLength = request.Content.Headers.ContentLength; - if (contentLength.HasValue && contentLength.Value != -1L) - { - canonicalizedString.AppendCanonicalizedElement(contentLength.Value.ToString(CultureInfo.InvariantCulture)); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - } - } - - /// - /// Appends the value of the Date header (or, optionally, the x-ms-date header) to the specified canonicalized string. - /// - /// The canonicalized string where the value is appended. - /// The request where the value is read from. - /// true if the value of the x-ms-date header can be used and is preferred; otherwise, false. - public static void AppendCanonicalizedDateHeader(CanonicalizedString canonicalizedString, HttpRequestMessage request, bool allowMicrosoftDateHeader = false) - { - string microsoftDateHeaderValue = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(request.Headers, Constants.HeaderConstants.Date); - if (string.IsNullOrEmpty(microsoftDateHeaderValue)) - { - canonicalizedString.AppendCanonicalizedElement(AuthenticationUtility.GetCanonicalizedHeaderValue(request.Headers.Date)); - } - else if (allowMicrosoftDateHeader) - { - canonicalizedString.AppendCanonicalizedElement(microsoftDateHeaderValue); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - } - } - - /// - /// Appends the values of the x-ms-* headers to the specified canonicalized string. - /// - /// The canonicalized string where the values are appended. - /// The request where the values are read from. - public static void AppendCanonicalizedCustomHeaders(CanonicalizedString canonicalizedString, HttpRequestMessage request) - { - CultureInfo sortingCulture = new CultureInfo("en-US"); - StringComparer sortingComparer = new CultureStringComparer(sortingCulture, false); - SortedDictionary> headers = new SortedDictionary>(sortingComparer); - - foreach (KeyValuePair> header in request.Headers) - { - string headerName = header.Key; - if (headerName.StartsWith(Constants.HeaderConstants.PrefixForStorageHeader, StringComparison.OrdinalIgnoreCase)) - { - headers.Add(headerName.ToLowerInvariant(), header.Value); - } - } - - if (request.Content != null) - { - foreach (KeyValuePair> header in request.Content.Headers) - { - string headerName = header.Key; - if (headerName.StartsWith(Constants.HeaderConstants.PrefixForStorageHeader, StringComparison.OrdinalIgnoreCase)) - { - headers.Add(headerName.ToLowerInvariant(), header.Value); - } - } - } - - StringBuilder canonicalizedElement = new StringBuilder(ExpectedHeaderNameAndValueLength); - foreach (KeyValuePair> header in headers) - { - canonicalizedElement.Clear(); - canonicalizedElement.Append(header.Key); - canonicalizedElement.Append(HeaderNameValueSeparator); - - foreach (string value in header.Value) - { - canonicalizedElement.Append(value.TrimStart().Replace("\r\n", string.Empty)); - canonicalizedElement.Append(HeaderValueDelimiter); - } - - canonicalizedString.AppendCanonicalizedElement(canonicalizedElement.ToString(0, canonicalizedElement.Length - 1)); - } - } -#else - /// - /// Gets the value of the x-ms-date or Date header. - /// - /// The request where the value is read from. - /// The value of the x-ms-date or Date header. - public static string GetPreferredDateHeaderValue(HttpWebRequest request) - { - string microsoftDateHeaderValue = request.Headers[Constants.HeaderConstants.Date]; - if (!string.IsNullOrEmpty(microsoftDateHeaderValue)) - { - return microsoftDateHeaderValue; - } - - return request.Headers[HttpRequestHeader.Date]; - } - - /// - /// Appends the value of the Content-Length header to the specified canonicalized string. - /// - /// The canonicalized string where the value is appended. - /// The request where the value is read from. - public static void AppendCanonicalizedContentLengthHeader(CanonicalizedString canonicalizedString, HttpWebRequest request) - { - if (request.ContentLength != -1L) - { - canonicalizedString.AppendCanonicalizedElement(request.ContentLength.ToString(CultureInfo.InvariantCulture)); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - } - } - - /// - /// Appends the value of the Date header (or, optionally, the x-ms-date header) to the specified canonicalized string. - /// - /// The canonicalized string where the value is appended. - /// The request where the value is read from. - /// true if the value of the x-ms-date header can be used and is preferred; otherwise, false. - public static void AppendCanonicalizedDateHeader(CanonicalizedString canonicalizedString, HttpWebRequest request, bool allowMicrosoftDateHeader = false) - { - string microsoftDateHeaderValue = request.Headers[Constants.HeaderConstants.Date]; - if (string.IsNullOrEmpty(microsoftDateHeaderValue)) - { - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.Date]); - } - else if (allowMicrosoftDateHeader) - { - canonicalizedString.AppendCanonicalizedElement(microsoftDateHeaderValue); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - } - } - - /// - /// Appends the values of the x-ms-* headers to the specified canonicalized string. - /// - /// The canonicalized string where the values are appended. - /// The request where the values are read from. - [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Reviewed.")] - public static void AppendCanonicalizedCustomHeaders(CanonicalizedString canonicalizedString, HttpWebRequest request) - { - List headerNames = new List(request.Headers.AllKeys.Length); - foreach (string headerName in request.Headers.AllKeys) - { - if (headerName.StartsWith(Constants.HeaderConstants.PrefixForStorageHeader, StringComparison.OrdinalIgnoreCase)) - { - headerNames.Add(headerName.ToLowerInvariant()); - } - } - - CultureInfo sortingCulture = new CultureInfo("en-US"); - StringComparer sortingComparer = StringComparer.Create(sortingCulture, false); - headerNames.Sort(sortingComparer); - - StringBuilder canonicalizedElement = new StringBuilder(ExpectedHeaderNameAndValueLength); - foreach (string headerName in headerNames) - { - string value = request.Headers[headerName]; - if (!string.IsNullOrEmpty(value)) - { - canonicalizedElement.Length = 0; - canonicalizedElement.Append(headerName); - canonicalizedElement.Append(HeaderNameValueSeparator); - canonicalizedElement.Append(value.TrimStart().Replace("\r\n", string.Empty)); - - canonicalizedString.AppendCanonicalizedElement(canonicalizedElement.ToString()); - } - } - } -#endif - - /// - /// Gets the canonicalized header value to use for the specified date/time or null if it does not have a value. - /// - /// The date/time. - /// The canonicalized header value to use for the specified date/time or null if it does not have a value. - public static string GetCanonicalizedHeaderValue(DateTimeOffset? value) - { - if (value.HasValue) - { - return HttpWebUtility.ConvertDateTimeToHttpString(value.Value); - } - - return null; - } - - /// - /// Gets the canonicalized resource string for the specified URI. - /// - /// The resource URI. - /// The name of the storage account. - /// true when using the Shared Key Lite authentication scheme or the table service; otherwise, false. - /// The canonicalized resource string. - [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Reviewed.")] - public static string GetCanonicalizedResourceString(Uri uri, string accountName, bool isSharedKeyLiteOrTableService = false) - { - StringBuilder canonicalizedResource = new StringBuilder(ExpectedResourceStringLength); - canonicalizedResource.Append('/'); - canonicalizedResource.Append(accountName); - canonicalizedResource.Append(uri.AbsolutePath); - - IDictionary queryParameters = HttpWebUtility.ParseQueryString(uri.Query); - if (!isSharedKeyLiteOrTableService) - { - List queryParameterNames = new List(queryParameters.Keys); - queryParameterNames.Sort(StringComparer.OrdinalIgnoreCase); - - foreach (string queryParameterName in queryParameterNames) - { - canonicalizedResource.Append('\n'); - canonicalizedResource.Append(queryParameterName.ToLowerInvariant()); - canonicalizedResource.Append(':'); - canonicalizedResource.Append(queryParameters[queryParameterName]); - } - } - else - { - // Add only the comp parameter - string compQueryParameterValue; - if (queryParameters.TryGetValue("comp", out compQueryParameterValue) && compQueryParameterValue != null) - { - canonicalizedResource.Append("?comp="); - canonicalizedResource.Append(compQueryParameterValue); - } - } - - return canonicalizedResource.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CommonUtility.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CommonUtility.cs deleted file mode 100644 index 7043560d32519..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CommonUtility.cs +++ /dev/null @@ -1,311 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Blob; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Xml; - -#if WINDOWS_DESKTOP - using System.Net; -#endif - - internal static class CommonUtility - { - /// - /// Create an ExecutionState object that can be used for pre-request operations - /// such as buffering user's data. - /// - /// Request options - /// Temporary ExecutionState object - internal static ExecutionState CreateTemporaryExecutionState(BlobRequestOptions options) - { - RESTCommand cmdWithTimeout = new RESTCommand(new StorageCredentials(), null /* Uri */); - if (options != null) - { - cmdWithTimeout.ApplyRequestOptions(options); - } - - return new ExecutionState(cmdWithTimeout, options.RetryPolicy, new OperationContext()); - } - - /// - /// Gets the first header value or null if no header values exist. - /// - /// The type of header objects contained in the enumerable. - /// An enumerable that contains header values. - /// The first header value or null if no header values exist. - public static string GetFirstHeaderValue(IEnumerable headerValues) where T : class - { - if (headerValues != null) - { - T result = headerValues.FirstOrDefault(); - if (result != null) - { - return result.ToString().TrimStart(); - } - } - - return null; - } - - /// - /// Throws an exception if the string is empty or null. - /// - /// The name of the parameter. - /// The value of the parameter. - /// Thrown if value is empty. - /// Thrown if value is null. - internal static void AssertNotNullOrEmpty(string paramName, string value) - { - AssertNotNull(paramName, value); - - if (string.IsNullOrEmpty(value)) - { - throw new ArgumentException(SR.ArgumentEmptyError, paramName); - } - } - - /// - /// Throw an exception if the value is null. - /// - /// The name of the parameter. - /// The value of the parameter. - /// Thrown if value is null. - internal static void AssertNotNull(string paramName, object value) - { - if (value == null) - { - throw new ArgumentNullException(paramName); - } - } - - /// - /// Throw an exception indicating argument is out of range. - /// - /// The name of the parameter. - /// The value of the parameter. - internal static void ArgumentOutOfRange(string paramName, object value) - { - throw new ArgumentOutOfRangeException(paramName, string.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRangeError, value)); - } - - /// - /// Throw an exception if the argument is out of bounds. - /// - /// The type of the value. - /// The name of the parameter. - /// The value of the parameter. - /// The minimum value for the parameter. - /// The maximum value for the parameter. - internal static void AssertInBounds(string paramName, T val, T min, T max) - where T : IComparable - { - if (val.CompareTo(min) < 0) - { - throw new ArgumentOutOfRangeException(paramName, string.Format(CultureInfo.InvariantCulture, SR.ArgumentTooSmallError, paramName, min)); - } - - if (val.CompareTo(max) > 0) - { - throw new ArgumentOutOfRangeException(paramName, string.Format(CultureInfo.InvariantCulture, SR.ArgumentTooLargeError, paramName, max)); - } - } - - /// - /// Throw an exception if the argument is out of bounds. - /// - /// The type of the value. - /// The name of the parameter. - /// The value of the parameter. - /// The minimum value for the parameter. - internal static void AssertInBounds(string paramName, T val, T min) - where T : IComparable - { - if (val.CompareTo(min) < 0) - { - throw new ArgumentOutOfRangeException(paramName, string.Format(CultureInfo.InvariantCulture, SR.ArgumentTooSmallError, paramName, min)); - } - } - - /// - /// Checks that the given timeout in within allowed bounds. - /// - /// The timeout to check. - /// The timeout is not within allowed bounds. - internal static void CheckTimeoutBounds(TimeSpan timeout) - { - CommonUtility.AssertInBounds("Timeout", timeout, TimeSpan.FromSeconds(1), Constants.MaximumAllowedTimeout); - } - - /// - /// Combines AssertNotNullOrEmpty and AssertInBounds for convenience. - /// - /// The name of the parameter. - /// Turns on or off null/empty checking. - /// The value of the parameter. - /// The maximum size of value. - internal static void CheckStringParameter(string paramName, bool canBeNullOrEmpty, string value, int maxSize) - { - if (!canBeNullOrEmpty) - { - AssertNotNullOrEmpty(value, paramName); - } - - AssertInBounds(value, paramName.Length, 0, maxSize); - } - - /// - /// Rounds up to seconds. - /// - /// The time span. - /// The time rounded to seconds. - internal static int RoundUpToSeconds(this TimeSpan timeSpan) - { - return (int)Math.Ceiling(timeSpan.TotalSeconds); - } - - /// - /// Determines if a URI requires path style addressing. - /// - /// The URI to check. - /// Returns true if the Uri uses path style addressing; otherwise, false. - internal static bool UsePathStyleAddressing(Uri uri) - { - if (uri.HostNameType != UriHostNameType.Dns) - { - return true; - } - - switch (uri.Port) - { - case 10000: - case 10001: - case 10002: - case 10003: - case 10004: - return true; - } - - return false; - } - - /// - /// Read the value of an element in the XML. - /// - /// The name of the element whose value is retrieved. - /// A reader that provides access to XML data. - /// A string representation of the element's value. - internal static string ReadElementAsString(string elementName, XmlReader reader) - { - string res = null; - - if (reader.IsStartElement(elementName)) - { - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - res = reader.ReadElementContentAsString(); - } - } - else - { - throw new XmlException(elementName); - } - - reader.MoveToContent(); - - return res; - } - - /// - /// Returns an enumerable collection of results that is retrieved lazily. - /// - /// The type of ResultSegment like Blob, Container, Queue and Table. - /// The segment generator. - /// >A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. - /// - internal static IEnumerable LazyEnumerable(Func> segmentGenerator, long maxResults) - { - ResultSegment currentSeg = segmentGenerator(null); - long count = 0; - while (true) - { - foreach (T result in currentSeg.Results) - { - yield return result; - count++; - if (count >= maxResults) - { - break; - } - } - - if (count >= maxResults) - { - break; - } - - if (currentSeg.ContinuationToken != null) - { - currentSeg = segmentGenerator(currentSeg.ContinuationToken); - } - else - { - break; - } - } - } - -#if WINDOWS_DESKTOP - /// - /// Applies the request optimizations such as disabling buffering and 100 continue. - /// - /// The request to be modified. - /// The length of the content, -1 if the content length is not settable. - internal static void ApplyRequestOptimizations(HttpWebRequest request, long length) - { - if (length >= Constants.DefaultBufferSize) - { - request.AllowWriteStreamBuffering = false; - } - - // Set the length of the stream if the value is known - if (length >= 0) - { - request.ContentLength = length; - } - -#if !WINDOWS_PHONE - // Disable the Expect 100-Continue - request.ServicePoint.Expect100Continue = false; -#endif - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CounterEvent.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CounterEvent.cs deleted file mode 100644 index 1ae45608bb20b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CounterEvent.cs +++ /dev/null @@ -1,97 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Threading; - - internal sealed class CounterEvent : IDisposable - { - private ManualResetEvent internalEvent = new ManualResetEvent(true); - private object counterLock = new object(); - private int counter = 0; - - /// - /// Gets a WaitHandle that is used to wait for the event to be set. - /// - /// A WaitHandle that is used to wait for the event to be set. - public WaitHandle WaitHandle - { - get - { - return this.internalEvent; - } - } - - /// - /// Increments the counter by one and thus sets the state of the event to non-signaled, causing threads to block. - /// - public void Increment() - { - lock (this.counterLock) - { - this.counter++; - this.internalEvent.Reset(); - } - } - - /// - /// Decrements the counter by one. If the counter reaches zero, sets the state of the event to signaled, allowing one or more waiting threads to proceed. - /// - public void Decrement() - { - lock (this.counterLock) - { - if (--this.counter == 0) - { - this.internalEvent.Set(); - } - } - } - - /// - /// Blocks the current thread until the CounterEvent is set. - /// - public void Wait() - { - this.internalEvent.WaitOne(); - } - - /// - /// Blocks the current thread until the CounterEvent is set, using a 32-bit signed integer to measure the timeout. - /// - /// The number of milliseconds to wait, or Infinite(-1) to wait indefinitely. - /// true if the CounterEvent was set; otherwise, false. - public bool Wait(int millisecondsTimeout) - { - return this.internalEvent.WaitOne(millisecondsTimeout); - } - - /// - /// Releases all resources used by the current instance of the CounterEvent class. - /// - public void Dispose() - { - if (this.internalEvent != null) - { - this.internalEvent.Dispose(); - this.internalEvent = null; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CryptoUtility.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CryptoUtility.cs deleted file mode 100644 index 624020102a1de..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/CryptoUtility.cs +++ /dev/null @@ -1,50 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ -#if WINDOWS_RT - using Windows.Security.Cryptography; - using Windows.Security.Cryptography.Core; - using Windows.Storage.Streams; -#else - using System; - using System.Security.Cryptography; - using System.Text; -#endif - - internal static class CryptoUtility - { - internal static string ComputeHmac256(byte[] key, string message) - { -#if WINDOWS_RT - MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA256"); - IBuffer keyMaterial = CryptographicBuffer.CreateFromByteArray(key); - CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyMaterial); - IBuffer messageBuffer = CryptographicBuffer.ConvertStringToBinary(message, BinaryStringEncoding.Utf8); - IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer); - return CryptographicBuffer.EncodeToBase64String(signedMessage); -#else - using (HashAlgorithm hashAlgorithm = new HMACSHA256(key)) - { - byte[] messageBuffer = Encoding.UTF8.GetBytes(message); - return Convert.ToBase64String(hashAlgorithm.ComputeHash(messageBuffer)); - } -#endif - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/Exceptions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/Exceptions.cs deleted file mode 100644 index 52e5f737f8236..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/Exceptions.cs +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - -#if WINDOWS_RT - using System.Globalization; - using System.IO; - using System.Net.Http; - using System.Threading.Tasks; -#endif - - internal class Exceptions - { -#if WINDOWS_RT - internal async static Task PopulateStorageExceptionFromHttpResponseMessage(HttpResponseMessage response, RequestResult currentResult) - { - if (!response.IsSuccessStatusCode) - { - try - { - currentResult.HttpStatusMessage = response.ReasonPhrase; - currentResult.HttpStatusCode = (int)response.StatusCode; - currentResult.ServiceRequestID = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.RequestIdHeader); - - string tempDate = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.Date); - currentResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate; - - if (response.Headers.ETag != null) - { - currentResult.Etag = response.Headers.ETag.ToString(); - } - - if (response.Content != null && response.Content.Headers.ContentMD5 != null) - { - currentResult.ContentMd5 = Convert.ToBase64String(response.Content.Headers.ContentMD5); - } - } - catch (Exception) - { - // no op - } - - try - { - Stream errStream = await response.Content.ReadAsStreamAsync(); - currentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(errStream.AsInputStream()); - } - catch (Exception) - { - // no op - } - - return new StorageException(currentResult, response.ReasonPhrase, null); - } - else - { - return null; - } - } -#endif - - internal static StorageException GenerateTimeoutException(RequestResult res, Exception inner) - { - if (res != null) - { - res.HttpStatusCode = 408; // RequestTimeout - } - - TimeoutException timeoutEx = new TimeoutException(SR.TimeoutExceptionMessage, inner); - return new StorageException(res, timeoutEx.Message, timeoutEx) - { - IsRetryable = false - }; - } - -#if WINDOWS_DESKTOP - internal static StorageException GenerateCancellationException(RequestResult res, Exception inner) - { - if (res != null) - { - res.HttpStatusCode = 306; - res.HttpStatusMessage = "Unused"; - } - - OperationCanceledException cancelEx = new OperationCanceledException(SR.OperationCanceled, inner); - return new StorageException(res, cancelEx.Message, cancelEx) { IsRetryable = false }; - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/HttpWebUtility.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/HttpWebUtility.cs deleted file mode 100644 index c68692ba2e8e0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/HttpWebUtility.cs +++ /dev/null @@ -1,146 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - -#if WINDOWS_RT - using System.Net.Http; -#else - using System.Net; -#endif - - /// - /// Provides helper functions for http request/response processing. - /// - internal static class HttpWebUtility - { - /// - /// Parse the http query string. - /// - /// Http query string. - /// - public static IDictionary ParseQueryString(string query) - { - Dictionary retVal = new Dictionary(); - if (string.IsNullOrEmpty(query)) - { - return retVal; - } - - if (query.StartsWith("?", StringComparison.Ordinal)) - { - if (query.Length == 1) - { - return retVal; - } - - query = query.Substring(1); - } - - string[] valuePairs = query.Split('&'); - foreach (string pair in valuePairs) - { - string key; - string value; - - int equalDex = pair.IndexOf("=", StringComparison.Ordinal); - if (equalDex < 0) - { - key = string.Empty; - value = Uri.UnescapeDataString(pair); - } - else - { - key = Uri.UnescapeDataString(pair.Substring(0, equalDex)); - value = Uri.UnescapeDataString(pair.Substring(equalDex + 1)); - } - - string existingValue; - if (retVal.TryGetValue(key, out existingValue)) - { - retVal[key] = string.Concat(existingValue, ",", value); - } - else - { - retVal[key] = value; - } - } - - return retVal; - } - - /// - /// Converts the DateTimeOffset object to an Http string of form: Sun, 28 Jan 2008 12:11:37 GMT. - /// - /// The DateTimeOffset object to convert to an Http string. - /// String of form: Sun, 28 Jan 2008 12:11:37 GMT. - public static string ConvertDateTimeToHttpString(DateTimeOffset dateTime) - { - // 'R' means rfc1123 date which is what the storage services use for all dates... - // It will be in the following format: - // Sun, 28 Jan 2008 12:11:37 GMT - return dateTime.UtcDateTime.ToString("R", CultureInfo.InvariantCulture); - } - -#if WINDOWS_RT - /// - /// Combine all the header values in the IEnumerable to a single comma separated string. - /// - /// An IEnumerable object representing the header values. - /// A comma separated string of header values. - public static string CombineHttpHeaderValues(IEnumerable headerValues) - { - if (headerValues == null) - { - return null; - } - - return (headerValues.Count() == 0) ? - null : - string.Join(",", headerValues); - } -#endif - -#if WINDOWS_DESKTOP - /// - /// Try to get the value of the specified header name. - /// - /// The Http web response from which to get the header value. - /// The name of the header whose value is to be retrieved. - /// The default value for the header that is returned if we can't get the actual header value. - /// A string representing the header value. - public static string TryGetHeader(HttpWebResponse resp, string headerName, string defaultValue) - { - string value = resp.Headers[headerName]; - if (string.IsNullOrEmpty(value)) - { - return defaultValue; - } - else - { - return value; - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/MD5Wrapper.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/MD5Wrapper.cs deleted file mode 100644 index 406d4a64d5151..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/MD5Wrapper.cs +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Diagnostics.CodeAnalysis; - -#if WINDOWS_RT - using System.Runtime.InteropServices.WindowsRuntime; - using Windows.Security.Cryptography; - using Windows.Security.Cryptography.Core; - using Windows.Storage.Streams; -#else - using System.Security.Cryptography; -#endif - - /// - /// Wrapper class for MD5. - /// - internal class MD5Wrapper : IDisposable - { - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - private readonly bool version1MD5 = CloudStorageAccount.UseV1MD5; - -#if WINDOWS_RT - private CryptographicHash hash = null; -#elif WINDOWS_PHONE - -#else - private MD5 hash = null; -#endif - - [SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", Justification = "Used as a hash, not encryption")] - internal MD5Wrapper() - { -#if WINDOWS_RT - this.hash = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); -#elif WINDOWS_PHONE - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); -#else - this.hash = this.version1MD5 ? MD5.Create() : new NativeMD5(); -#endif - } - - /// - /// Calculates an on-going hash using the input byte array. - /// - /// The input array used for calculating the hash. - /// The offset in the input buffer to calculate from. - /// The number of bytes to use from input. - internal void UpdateHash(byte[] input, int offset, int count) - { - if (count > 0) - { -#if WINDOWS_RT - this.hash.Append(input.AsBuffer(offset, count)); -#elif WINDOWS_PHONE - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); -#else - this.hash.TransformBlock(input, offset, count, null, 0); -#endif - } - } - - /// - /// Retrieves the string representation of the hash. (Completes the creation of the hash). - /// - /// String representation of the computed hash value. - internal string ComputeHash() - { -#if WINDOWS_RT - IBuffer md5HashBuff = this.hash.GetValueAndReset(); - return CryptographicBuffer.EncodeToBase64String(md5HashBuff); -#elif WINDOWS_PHONE - throw new NotSupportedException(SR.WindowsPhoneDoesNotSupportMD5); -#else - this.hash.TransformFinalBlock(new byte[0], 0, 0); - return Convert.ToBase64String(this.hash.Hash); -#endif - } - - public void Dispose() - { -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - if (this.hash != null) - { - ((IDisposable)this.hash).Dispose(); - this.hash = null; - } -#endif - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/NavigationHelper.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/NavigationHelper.cs deleted file mode 100644 index a7c181f2a4e81..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/NavigationHelper.cs +++ /dev/null @@ -1,544 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - - /// - /// Contains methods for dealing with navigation. - /// - internal static class NavigationHelper - { - /// - /// The name of the root container. - /// - public const string RootContainerName = "$root"; - - /// - /// Used in address parsing. - /// - public const string Slash = "/"; - - /// - /// Used in address parsing. - /// - public const string Dot = "."; - - /// - /// Used in address parsing. - /// - public const char SlashChar = '/'; - - /// - /// Used to split string on slash. - /// - public static readonly char[] SlashAsSplitOptions = Slash.ToCharArray(); - - /// - /// Used to split hostname. - /// - public static readonly char[] DotAsSplitOptions = Dot.ToCharArray(); - - /// - /// Retrieves the container part of a storage Uri, or "$root" if the container is implicit. - /// - /// The blob address. - /// If set to true use path style Uris. - /// Name of the container. - /// - /// The trailing slash is always removed. - /// - /// GetContainerName(new Uri("http://test.blob.core.windows.net/mycontainer/myfolder/myblob")) will return "mycontainer" - /// GetContainerName(new Uri("http://test.blob.core.windows.net/mycontainer/")) will return "mycontainer" - /// GetContainerName(new Uri("http://test.blob.core.windows.net/myblob")) will return "$root" - /// GetContainerName(new Uri("http://test.blob.core.windows.net/")) will throw ArgumentException - /// - /// - internal static string GetContainerName(Uri blobAddress, bool? usePathStyleUris) - { - string containerName; - string blobName; - - GetContainerNameAndBlobName(blobAddress, usePathStyleUris, out containerName, out blobName); - - return containerName; - } - - /// - /// Retrieves the blob part of a storage Uri. - /// - /// The blob address. - /// If set to true use path style Uris. - /// The name of the blob. - internal static string GetBlobName(Uri blobAddress, bool? usePathStyleUris) - { - string containerName; - string blobName; - - GetContainerNameAndBlobName(blobAddress, usePathStyleUris, out containerName, out blobName); - - return Uri.UnescapeDataString(blobName); - } - - /// - /// Retrieves the complete container address from a storage Uri - /// Example GetContainerAddress(new Uri("http://test.blob.core.windows.net/mycontainer/myfolder/myblob")) - /// will return http://test.blob.core.windows.net/mycontainer. - /// - /// The blob address. - /// True to use path style Uris. - /// Uri of the container. - internal static Uri GetContainerAddress(Uri blobAddress, bool? usePathStyleUris) - { - string containerName; - Uri containerAddress; - - GetContainerNameAndAddress(blobAddress, usePathStyleUris, out containerName, out containerAddress); - - return containerAddress; - } - - /// - /// Retrieves the parent name from a storage Uri. - /// - /// The blob address. - /// The delimiter. - /// If set to true use path style Uris. - /// The name of the parent. - /// - /// Adds the trailing delimiter as the prefix returned by the storage REST api always contains the delimiter. - /// - /// - /// GetParentName(new Uri("http://test.blob.core.windows.net/mycontainer/myfolder/myblob", "/")) will return "/mycontainer/myfolder/" - /// GetParentName(new Uri("http://test.blob.core.windows.net/mycontainer/myfolder|myblob", "|") will return "/mycontainer/myfolder|" - /// GetParentName(new Uri("http://test.blob.core.windows.net/mycontainer/myblob", "/") will return "/mycontainer/" - /// GetParentName(new Uri("http://test.blob.core.windows.net/mycontainer/", "/") will return "/mycontainer/" - /// - internal static string GetParentName(Uri blobAddress, string delimiter, bool? usePathStyleUris) - { - CommonUtility.AssertNotNull("blobAbsoluteUriString", blobAddress); - CommonUtility.AssertNotNullOrEmpty("delimiter", delimiter); - - string containerName; - Uri containerUri; - GetContainerNameAndAddress(blobAddress, usePathStyleUris, out containerName, out containerUri); - containerName += NavigationHelper.Slash; - - // Get the blob path as the rest of the Uri - Uri blobPathUri = containerUri.MakeRelativeUri(blobAddress); - string blobPath = blobPathUri.OriginalString; - - delimiter = Uri.EscapeUriString(delimiter); - if (blobPath.EndsWith(delimiter, StringComparison.Ordinal)) - { - blobPath = blobPath.Substring(0, blobPath.Length - delimiter.Length); - } - - string parentName = null; - - if (string.IsNullOrEmpty(blobPath)) - { - // Case 1 /[Delimiter]*? => / - // Parent of container is container itself - parentName = null; - } - else - { - int parentLength = blobPath.LastIndexOf(delimiter, StringComparison.Ordinal); - - if (parentLength <= 0) - { - // Case 2 // - // Parent of a folder is container - parentName = null; - } - else - { - // Case 3 ///[/]* - // Parent of blob is folder - parentName = Uri.UnescapeDataString(blobPath.Substring(0, parentLength + delimiter.Length)); - if (parentName == containerName) - { - parentName = null; - } - } - } - - return parentName; - } - - /// - /// Retrieves the parent address for a blob Uri. - /// - /// The blob address. - /// The delimiter. - /// If set to true use path style Uris. - /// The address of the parent. - /// - /// GetParentName(new Uri("http://test.blob.core.windows.net/mycontainer/myfolder/myblob", null)) - /// will return "http://test.blob.core.windows.net/mycontainer/myfolder/" - /// - internal static Uri GetParentAddress(Uri blobAddress, string delimiter, bool? usePathStyleUris) - { - string parentName = GetParentName(blobAddress, delimiter, usePathStyleUris); - if (parentName == null) - { - return null; - } - - Uri parentUri = NavigationHelper.AppendPathToUri(NavigationHelper.GetServiceClientBaseAddress(blobAddress, usePathStyleUris), parentName); - return parentUri; - } - - /// - /// Gets the service client base address. - /// - /// The address Uri. - /// The use path style Uris. - /// The base address of the client. - /// - /// GetServiceClientBaseAddress("http://testaccount.blob.core.windows.net/testcontainer/blob1") - /// returns "http://testaccount.blob.core.windows.net" - /// - internal static Uri GetServiceClientBaseAddress(Uri addressUri, bool? usePathStyleUris) - { - if (usePathStyleUris == null) - { - // Automatically determine whether to use path style vs host style uris - usePathStyleUris = CommonUtility.UsePathStyleAddressing(addressUri); - } - - Uri authority = new Uri(addressUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped)); - if (usePathStyleUris.Value) - { - // Path style uri - string[] segments = addressUri.Segments; - if (segments.Length < 2) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.PathStyleUriMissingAccountNameInformation); - throw new ArgumentException("address", error); - } - - return new Uri(authority, segments[1]); - } - else - { - return authority; - } - } - - /// - /// Appends a path to a URI correctly using "/" as separator. - /// - /// The base URI. - /// The relative or absolute URI. - /// The appended Uri. - /// - /// AppendPathToUri(new Uri("http://test.blob.core.windows.net/test", "abc") - /// will return "http://test.blob.core.windows.net/test/abc" - /// AppendPathToUri(new Uri("http://test.blob.core.windows.net/test"), "http://test.blob.core.windows.net/test/abc") - /// will return "http://test.blob.core.windows.net/test/abc" - /// - internal static Uri AppendPathToUri(Uri uri, string relativeOrAbsoluteUri) - { - return AppendPathToUri(uri, relativeOrAbsoluteUri, NavigationHelper.Slash); - } - - /// - /// Append a relative path to a URI, handling trailing slashes appropriately. - /// - /// The base URI. - /// The relative or absolute URI. - /// The separator. - /// The appended Uri. - internal static Uri AppendPathToUri(Uri uri, string relativeOrAbsoluteUri, string sep) - { - Uri relativeUri; - - // Because of URI's Scheme, URI.TryCreate() can't differentiate a string with colon from an absolute URI. - // A workaround is added here to verify if a given string is an absolute URI. - if (Uri.TryCreate(relativeOrAbsoluteUri, UriKind.Absolute, out relativeUri) && (relativeUri.Scheme == "http" || relativeUri.Scheme == "https")) - { - // Handle case if relPath is an absolute Uri - if (uri.IsBaseOf(relativeUri)) - { - return relativeUri; - } - else - { - // Happens when using fiddler, DNS aliases, or potentially NATs - Uri absoluteUri = new Uri(relativeOrAbsoluteUri); - return new Uri(uri, absoluteUri.AbsolutePath); - } - } - - sep = Uri.EscapeUriString(sep); - relativeOrAbsoluteUri = Uri.EscapeUriString(relativeOrAbsoluteUri); - - UriBuilder ub = new UriBuilder(uri); - string appendString = null; - if (ub.Path.EndsWith(sep, StringComparison.Ordinal)) - { - appendString = relativeOrAbsoluteUri; - } - else - { - appendString = sep + relativeOrAbsoluteUri; - } - - ub.Path += appendString; - return ub.Uri; - } - - /// - /// Get container name from address for styles of paths - /// Example: http://test.blob.core.windows.net/container/blob => container - /// http://127.0.0.1:10000/test/container/blob => container. - /// - /// The container Uri. - /// If set to true use path style Uris. - /// The container name. - internal static string GetContainerNameFromContainerAddress(Uri uri, bool? usePathStyleUris) - { - if (usePathStyleUris == null) - { - // Automatically determine whether to use path style vs host style uris - usePathStyleUris = CommonUtility.UsePathStyleAddressing(uri); - } - - if (usePathStyleUris.Value) - { - string[] parts = uri.AbsolutePath.Split(NavigationHelper.SlashAsSplitOptions); - - if (parts.Length < 3) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.MissingAccountInformationInUri, uri.AbsoluteUri); - throw new InvalidOperationException(errorMessage); - } - - return parts[2]; - } - else - { - return uri.AbsolutePath.Substring(1); - } - } - - /// - /// Gets the canonical path from creds. - /// - /// The credentials. - /// The absolute path. - /// The canonical path. - internal static string GetCanonicalPathFromCreds(StorageCredentials credentials, string absolutePath) - { - string account = credentials.AccountName; - - if (account == null) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASSignatureForGivenCred); - throw new InvalidOperationException(errorMessage); - } - - return NavigationHelper.Slash + account + absolutePath; - } - - /// - /// Similar to getting container name from Uri. - /// - /// The queue Uri. - /// If set to true use path style Uris. - /// The queue name. - internal static string GetQueueNameFromUri(Uri uri, bool? usePathStyleUris) - { - return GetContainerNameFromContainerAddress(uri, usePathStyleUris); - } - - /// - /// Extracts a table name from the table's Uri. - /// - /// The queue Uri. - /// If set to true use path style Uris. - /// The queue name. - internal static string GetTableNameFromUri(Uri uri, bool? usePathStyleUris) - { - return GetContainerNameFromContainerAddress(uri, usePathStyleUris); - } - - /// - /// Retrieve the container address and address. - /// - /// The blob address. - /// True to use path style Uris. - /// Name of the container. - /// The container URI. - private static void GetContainerNameAndAddress(Uri blobAddress, bool? usePathStyleUris, out string containerName, out Uri containerUri) - { - containerName = GetContainerName(blobAddress, usePathStyleUris); - containerUri = NavigationHelper.AppendPathToUri(GetServiceClientBaseAddress(blobAddress, usePathStyleUris), containerName); - } - - /// - /// Retrieve the container name and the blob name from a blob address. - /// - /// The blob address. - /// If set to true use path style Uris. - /// The resulting container name. - /// The resulting blob name. - private static void GetContainerNameAndBlobName(Uri blobAddress, bool? usePathStyleUris, out string containerName, out string blobName) - { - CommonUtility.AssertNotNull("blobAddress", blobAddress); - - if (usePathStyleUris == null) - { - // Automatically determine whether to use path style vs host style uris - usePathStyleUris = CommonUtility.UsePathStyleAddressing(blobAddress); - } - - string[] addressParts = blobAddress.Segments; - - int containerIndex = usePathStyleUris.Value ? 2 : 1; - int firstBlobIndex = containerIndex + 1; - - if (addressParts.Length - 1 < containerIndex) - { - // No reference appears to any container or blob - string error = string.Format(CultureInfo.CurrentCulture, SR.MissingContainerInformation, blobAddress); - throw new ArgumentException(error, "blobAddress"); - } - else if (addressParts.Length - 1 == containerIndex) - { - // This is either the root directory of a container or a blob in the root container - string containerOrBlobName = addressParts[containerIndex]; - if (containerOrBlobName[containerOrBlobName.Length - 1] == SlashChar) - { - // This is the root directory of a container - containerName = containerOrBlobName.Trim(SlashChar); - blobName = string.Empty; - } - else - { - // This is a blob implicitly in the root container - containerName = RootContainerName; - blobName = containerOrBlobName; - } - } - else - { - // This is a blob in an explicit container - containerName = addressParts[containerIndex].Trim(SlashChar); - string[] blobNameSegments = new string[addressParts.Length - firstBlobIndex]; - Array.Copy(addressParts, firstBlobIndex, blobNameSegments, 0, blobNameSegments.Length); - blobName = string.Concat(blobNameSegments); - } - } - - /// - /// Parses the snapshot time. - /// - /// The snapshot time. - /// The parsed snapshot time. - internal static DateTimeOffset ParseSnapshotTime(string snapshot) - { - DateTimeOffset snapshotTime; - - if (!DateTimeOffset.TryParse( - snapshot, - CultureInfo.InvariantCulture, - DateTimeStyles.AdjustToUniversal, - out snapshotTime)) - { - CommonUtility.ArgumentOutOfRange("snapshot", snapshot); - } - - return snapshotTime; - } - - /// - /// Parse Uri for SAS (Shared access signature) information. - /// - /// The complete Uri. - /// The credentials to use. - /// The parsed snapshot. - /// The blob URI without credentials or snapshot info - /// address - /// - /// Validate that no other query parameters are passed in. - /// Any SAS information will be recorded as corresponding credentials instance. - /// If credentials is passed in and it does not match the SAS information found, an - /// exception will be thrown. - /// Otherwise a new client is created based on SAS information or as anonymous credentials. - /// - internal static Uri ParseBlobQueryAndVerify(Uri address, out StorageCredentials parsedCredentials, out DateTimeOffset? parsedSnapshot) - { - CommonUtility.AssertNotNull("address", address); - if (!address.IsAbsoluteUri) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.RelativeAddressNotPermitted, address.ToString()); - throw new ArgumentException(errorMessage, "address"); - } - - IDictionary queryParameters = HttpWebUtility.ParseQueryString(address.Query); - - parsedSnapshot = null; - string snapshot; - if (queryParameters.TryGetValue(Constants.QueryConstants.Snapshot, out snapshot)) - { - if (!string.IsNullOrEmpty(snapshot)) - { - parsedSnapshot = ParseSnapshotTime(snapshot); - } - } - - parsedCredentials = SharedAccessSignatureHelper.ParseQuery(queryParameters, true); - return new Uri(address.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped)); - } - - /// - /// Parse Uri for SAS (Shared access signature) information. - /// - /// The complete Uri. - /// The credentials to use. - /// - /// Validate that no other query parameters are passed in. - /// Any SAS information will be recorded as corresponding credentials instance. - /// If credentials is passed in and it does not match the SAS information found, an - /// exception will be thrown. - /// Otherwise a new client is created based on SAS information or as anonymous credentials. - /// - internal static Uri ParseQueueTableQueryAndVerify(Uri address, out StorageCredentials parsedCredentials) - { - CommonUtility.AssertNotNull("address", address); - if (!address.IsAbsoluteUri) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.RelativeAddressNotPermitted, address.ToString()); - throw new ArgumentException(errorMessage, "address"); - } - - IDictionary queryParameters = HttpWebUtility.ParseQueryString(address.Query); - - parsedCredentials = SharedAccessSignatureHelper.ParseQuery(queryParameters, false); - return new Uri(address.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped)); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/PlatformAgnosticReflectionExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/PlatformAgnosticReflectionExtensions.cs deleted file mode 100644 index 09fa3b09c44f4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/PlatformAgnosticReflectionExtensions.cs +++ /dev/null @@ -1,86 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - - /// - /// Represents a canonicalized string used in authenticating a request against the azure service. - /// - internal static class PlatformAgnosticReflectionExtensions - { - public static IEnumerable FindStaticMethods(this Type type, string name) - { -#if WINDOWS_RT - return type.GetRuntimeMethods(); -#else - // Note currently this looks for nonpublic statics and instance methods, may need to be updated in future to accomodate publics - return type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).Where((m) => m.Name == name); -#endif - } - - public static IEnumerable FindMethods(this Type type) - { -#if WINDOWS_RT - return type.GetRuntimeMethods(); -#else - return type.GetMethods(); -#endif - } - - public static MethodInfo FindMethod(this Type type, string name, Type[] parameters) - { -#if WINDOWS_RT - return type.GetRuntimeMethod(name, parameters); -#else - return type.GetMethod(name, parameters); -#endif - } - - public static PropertyInfo FindProperty(this Type type, string name) - { -#if WINDOWS_RT - return type.GetRuntimeProperty(name); -#else - // Currently this looks for instance public / non publics, may need to be updated to support wider selection - return type.GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); -#endif - } - - public static MethodInfo FindGetProp(this PropertyInfo property) - { -#if WINDOWS_RT - return property.GetMethod; -#else - return property.GetGetMethod(); -#endif - } - - public static MethodInfo FindSetProp(this PropertyInfo property) - { -#if WINDOWS_RT - return property.SetMethod; -#else - return property.GetSetMethod(); -#endif - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamDescriptor.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamDescriptor.cs deleted file mode 100644 index dbbfc184e28ae..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamDescriptor.cs +++ /dev/null @@ -1,51 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System.Threading; - - /// - /// Provides properties to keep track of Md5 hash / Length of a stream as it is being copied. - /// - internal class StreamDescriptor - { - private long length = 0; - - public long Length - { - get { return Interlocked.Read(ref this.length); } - set { Interlocked.Exchange(ref this.length, value); } - } - - private volatile string md5 = null; - - public string Md5 - { - get { return this.md5; } - set { this.md5 = value; } - } - - private volatile MD5Wrapper md5HashRef = null; - - public MD5Wrapper Md5HashRef - { - get { return this.md5HashRef; } - set { this.md5HashRef = value; } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamExtensions.cs deleted file mode 100644 index 4ee52d2aef2fb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Core/Util/StreamExtensions.cs +++ /dev/null @@ -1,353 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Threading; - -#if WINDOWS_RT - using System.Threading.Tasks; -#endif - - /// - /// Provides stream helper methods that allow us to copy streams and measure the stream size. - /// - internal static class StreamExtensions - { - [DebuggerNonUserCode] - internal static int GetBufferSize(Stream inStream) - { - if (inStream.CanSeek && inStream.Length - inStream.Position > 0) - { - return (int)Math.Min(inStream.Length - inStream.Position, (long)Constants.DefaultBufferSize); - } - else - { - return Constants.DefaultBufferSize; - } - } - -#if !WINDOWS_RT - /// - /// Reads synchronously the specified content of the stream and writes it to the given output stream. - /// - /// The origin stream. - /// The destination stream. - /// Number of bytes to copy from source stream to destination stream. Cannot be passed with a value for maxLength. - /// Maximum length of the stream to write. - /// true to calculate the MD5 hash. - /// A boolean indicating whether the write happens synchronously. - /// An object that stores state of the operation. - /// State of the stream copy. - /// stream - [DebuggerNonUserCode] - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Reviewed")] - internal static void WriteToSync(this Stream stream, Stream toStream, long? copyLength, long? maxLength, bool calculateMd5, bool syncRead, ExecutionState executionState, StreamDescriptor streamCopyState) - { - if (copyLength.HasValue && maxLength.HasValue) - { - throw new ArgumentException(SR.StreamLengthMismatch); - } - - if (stream.CanSeek && maxLength.HasValue && stream.Length - stream.Position > maxLength) - { - throw new InvalidOperationException(SR.StreamLengthError); - } - - if (stream.CanSeek && copyLength.HasValue && stream.Length - stream.Position < copyLength) - { - throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - - byte[] buffer = new byte[GetBufferSize(stream)]; - - if (streamCopyState != null && calculateMd5 && streamCopyState.Md5HashRef == null) - { - streamCopyState.Md5HashRef = new MD5Wrapper(); - } - - RegisteredWaitHandle waitHandle = null; - ManualResetEvent completedEvent = null; - if (!syncRead && executionState.OperationExpiryTime.HasValue) - { - completedEvent = new ManualResetEvent(false); - waitHandle = ThreadPool.RegisterWaitForSingleObject( - completedEvent, - StreamExtensions.MaximumCopyTimeCallback, - executionState, - executionState.RemainingTimeout, - true); - } - - try - { - long? bytesRemaining = copyLength; - int readCount; - do - { - if (executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0) - { - throw Exceptions.GenerateTimeoutException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null); - } - - // Determine how many bytes to read this time so that no more than copyLength bytes are read - int bytesToRead = MinBytesToRead(bytesRemaining, buffer.Length); - - if (bytesToRead == 0) - { - break; - } - - // Read synchronously or asynchronously - readCount = syncRead - ? stream.Read(buffer, 0, bytesToRead) - : stream.EndRead(stream.BeginRead(buffer, 0, bytesToRead, null /* Callback */, null /* State */)); - - // Decrement bytes to write from bytes read - if (bytesRemaining.HasValue) - { - bytesRemaining -= readCount; - } - - // Write - if (readCount > 0) - { - toStream.Write(buffer, 0, readCount); - - // Update the StreamDescriptor after the bytes are successfully committed to the output stream - if (streamCopyState != null) - { - streamCopyState.Length += readCount; - - if (maxLength.HasValue && streamCopyState.Length > maxLength.Value) - { - throw new InvalidOperationException(SR.StreamLengthError); - } - - if (streamCopyState.Md5HashRef != null) - { - streamCopyState.Md5HashRef.UpdateHash(buffer, 0, readCount); - } - } - } - } - while (readCount != 0); - - if (bytesRemaining.HasValue && bytesRemaining != 0) - { - throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - } - catch (Exception) - { - if (executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0) - { - throw Exceptions.GenerateTimeoutException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null); - } - else - { - throw; - } - } - finally - { - if (waitHandle != null) - { - waitHandle.Unregister(null); - } - - if (completedEvent != null) - { - completedEvent.Close(); - } - } - - if (streamCopyState != null && streamCopyState.Md5HashRef != null) - { - streamCopyState.Md5 = streamCopyState.Md5HashRef.ComputeHash(); - streamCopyState.Md5HashRef = null; - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "If aborting the request fails, we can still continue executing it.")] - private static void MaximumCopyTimeCallback(object state, bool timedOut) - { - ExecutionState executionState = (ExecutionState)state; - - if (timedOut) - { - if (executionState.Req != null) - { - try - { - executionState.ReqTimedOut = true; - executionState.Req.Abort(); - } - catch (Exception) - { - // no op - } - } - } - } - - private static int MinBytesToRead(long? val1, int val2) - { - if (val1.HasValue && val1 < val2) - { - return (int)val1; - } - - return val2; - } -#endif - -#if WINDOWS_RT - /// - /// Asynchronously reads the entire content of the stream and writes it to the given output stream. - /// - /// The origin stream. - /// The destination stream. - /// Number of bytes to copy from source stream to destination stream. Cannot be passed with a value for maxLength. - /// Maximum length of the source stream. Cannot be passed with a value for copyLength. - /// Bool value indicating whether the Md5 should be calculated. - /// An object that stores state of the operation. - /// An object that represents the current state for the copy operation. - /// A CancellationToken to observe while waiting for the copy to complete. - /// The task object representing the asynchronous operation. - internal static async Task WriteToAsync(this Stream stream, Stream toStream, long? copyLength, long? maxLength, bool calculateMd5, ExecutionState executionState, StreamDescriptor streamCopyState, CancellationToken token) - { - if (copyLength.HasValue && maxLength.HasValue) - { - throw new ArgumentException(SR.StreamLengthMismatch); - } - - if (stream.CanSeek && maxLength.HasValue && stream.Length - stream.Position > maxLength) - { - throw new InvalidOperationException(SR.StreamLengthError); - } - - if (stream.CanSeek && copyLength.HasValue && stream.Length - stream.Position < copyLength) - { - throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - - if (streamCopyState != null && calculateMd5 && streamCopyState.Md5HashRef == null) - { - streamCopyState.Md5HashRef = new MD5Wrapper(); - } - - if (executionState.OperationExpiryTime.HasValue) - { - // Setup token for timeout - CancellationTokenSource cts = new CancellationTokenSource(executionState.RemainingTimeout); - CancellationToken tokenWithTimeout = cts.Token; - - // Hookup user's token - token.Register(() => cts.Cancel()); - - // Switch tokens - token = tokenWithTimeout; - } - - byte[] buffer = new byte[GetBufferSize(stream)]; - long? bytesRemaining = copyLength; - int readCount; - do - { - // Determine how many bytes to read this time so that no more than count bytes are read - int bytesToRead = bytesRemaining.HasValue && bytesRemaining < buffer.Length ? (int)bytesRemaining : buffer.Length; - - if (bytesToRead == 0) - { - break; - } - - readCount = await stream.ReadAsync(buffer, 0, bytesToRead, token); - - if (bytesRemaining.HasValue) - { - bytesRemaining -= readCount; - } - - if (readCount > 0) - { - await toStream.WriteAsync(buffer, 0, readCount, token); - - // Update the StreamDescriptor after the bytes are successfully committed to the output stream - if (streamCopyState != null) - { - streamCopyState.Length += readCount; - - if (maxLength.HasValue && streamCopyState.Length > maxLength.Value) - { - throw new InvalidOperationException(SR.StreamLengthError); - } - - if (streamCopyState.Md5HashRef != null) - { - streamCopyState.Md5HashRef.UpdateHash(buffer, 0, readCount); - } - } - } - } - while (readCount > 0); - - if (bytesRemaining.HasValue && bytesRemaining != 0) - { - throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - - // Streams opened with AsStreamForWrite extension need to be flushed - // to write all buffered data to the underlying Windows Runtime stream. - await toStream.FlushAsync(); - - if (streamCopyState != null && streamCopyState.Md5HashRef != null) - { - streamCopyState.Md5 = streamCopyState.Md5HashRef.ComputeHash(); - streamCopyState.Md5HashRef = null; - } - } - -#elif WINDOWS_DESKTOP - /// - /// Asynchronously reads the entire content of the stream and writes it to the given output stream. - /// - /// The result type of the ExecutionState - /// The origin stream. - /// The destination stream. - /// Number of bytes to copy from source stream to destination stream. Cannot be passed with a value for maxLength. - /// Maximum length of the source stream. Cannot be passed with a value for copyLength. - /// Bool value indicating whether the Md5 should be calculated. - /// An object that stores state of the operation. - /// State of the stream copy. - /// The action taken when the execution is completed. - [DebuggerNonUserCode] - internal static void WriteToAsync(this Stream stream, Stream toStream, long? copyLength, long? maxLength, bool calculateMd5, ExecutionState executionState, StreamDescriptor streamCopyState, Action> completed) - { - AsyncStreamCopier copier = new AsyncStreamCopier(stream, toStream, executionState, GetBufferSize(stream), calculateMd5, streamCopyState); - copier.StartCopyStream(completed, copyLength, maxLength); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/DoesServiceRequest.cs b/microsoft-azure-api/Services/Storage/Lib/Common/DoesServiceRequest.cs deleted file mode 100644 index 9510d447e2e24..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/DoesServiceRequest.cs +++ /dev/null @@ -1,35 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Specifies that the method will make one or more requests to the storage service. - /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Back compatibility.")] - [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)] -#if WINDOWS_RT - internal -#else - public -#endif - sealed class DoesServiceRequest : System.Attribute - { - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/IBufferManager.cs b/microsoft-azure-api/Services/Storage/Lib/Common/IBufferManager.cs deleted file mode 100644 index 3db8b34b256bf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/IBufferManager.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ -#if WINDOWS_RT - using System.Runtime.InteropServices.WindowsRuntime; -#endif - - /// - /// An interface that allows clients to provide a buffer manager to a given service client. This interface is patterned after - /// the System.ServiceModel.Channels.BufferManager class. - /// - public interface IBufferManager - { - /// - /// Returns a buffer to the pool. - /// - /// A reference to the buffer being returned. - /// Buffer reference cannot be null. - /// Length of buffer does not match the pool's buffer length property. -#if WINDOWS_RT - void ReturnBuffer([ReadOnlyArray] byte[] buffer); -#else - void ReturnBuffer(byte[] buffer); -#endif - - /// - /// Gets a buffer of at least the specified size from the pool. - /// - /// The size, in bytes, of the requested buffer. - /// The value specified for cannot be less than zero. - /// A byte array that is the requested size of the buffer. - byte[] TakeBuffer(int bufferSize); - - /// - /// Gets the size, in bytes, of the buffers managed by the given pool. Note that the buffer manager must return buffers of the exact size requested by the client. - /// - /// The size, in bytes, of the buffers managed by the given pool. - int GetDefaultBufferSize(); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/IContinuationToken.cs b/microsoft-azure-api/Services/Storage/Lib/Common/IContinuationToken.cs deleted file mode 100644 index 771f55dacf6d0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/IContinuationToken.cs +++ /dev/null @@ -1,28 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - /// - /// An interface required for continuation token types. - /// - /// The , , - /// and classes implement the interface. - public interface IContinuationToken - { - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/IRequestOptions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/IRequestOptions.cs deleted file mode 100644 index b04645b1945bb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/IRequestOptions.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using System; - - /// - /// An interface required for request option types. - /// - /// The , , and classes implement the interface. - public interface IRequestOptions - { - /// - /// Gets or sets the retry policy for the request. - /// - /// The retry policy delegate. - IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the server timeout for the request. - /// - /// The client and server timeout interval for the request. - TimeSpan? ServerTimeout { get; set; } - - /// - /// Gets or sets the maximum execution time across all potential retries. - /// - /// The maximum execution time across all potential retries. - TimeSpan? MaximumExecutionTime { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/LogLevel.cs b/microsoft-azure-api/Services/Storage/Lib/Common/LogLevel.cs deleted file mode 100644 index 86385380ce9f8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/LogLevel.cs +++ /dev/null @@ -1,50 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - /// - /// Specifies what messages to output to the log. - /// - public enum LogLevel - { - /// - /// Output no tracing and debugging messages. - /// - Off = 0, - - /// - /// Output error-handling messages. - /// - Error, - - /// - /// Output warnings and error-handling messages. - /// - Warning, - - /// - /// Output informational messages, warnings, and error-handling messages. - /// - Informational, - - /// - /// Output all debugging and tracing messages. - /// - Verbose, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/OperationContext.cs b/microsoft-azure-api/Services/Storage/Lib/Common/OperationContext.cs deleted file mode 100644 index 0e9b7c84150df..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/OperationContext.cs +++ /dev/null @@ -1,167 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents the context for a request operation against the storage service, and provides additional runtime information about its execution. - /// - public sealed class OperationContext - { - static OperationContext() - { - OperationContext.DefaultLogLevel = LogLevel.Verbose; - } - - /// - /// Initializes a new instance of the class. - /// - public OperationContext() - { - this.ClientRequestID = Guid.NewGuid().ToString(); - this.LogLevel = OperationContext.DefaultLogLevel; - } - - #region Headers - - /// - /// Gets or sets additional headers on the request, for example, for proxy or logging information. - /// - /// A object containing additional header information. - public IDictionary UserHeaders { get; set; } - - /// - /// Gets or sets the client request ID. - /// - /// The client request ID. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Justification = "Back compatibility.")] - public string ClientRequestID { get; set; } - - #endregion - - #region Events - - /// - /// Gets or sets the default logging level to be used for subsequently created instances of the class. - /// - /// A value of type that specifies which events are logged by default by instances of the . - public static LogLevel DefaultLogLevel { get; set; } - - /// - /// Gets or sets the logging level to be used for an instance of the class. - /// - /// A value of type that specifies which events are logged by the . - public LogLevel LogLevel { get; set; } - - /// - /// Occurs immediately before a request is signed. - /// - public event EventHandler SendingRequest; - - /// - /// Occurs when a response is received from the server. - /// - public event EventHandler ResponseReceived; - - internal void FireSendingRequest(RequestEventArgs args) - { - EventHandler handler = this.SendingRequest; - if (handler != null) - { - handler(this, args); - } - } - - internal void FireResponseReceived(RequestEventArgs args) - { - EventHandler handler = this.ResponseReceived; - if (handler != null) - { - handler(this, args); - } - } - #endregion - - #region Times -#if WINDOWS_RT - /// - /// Gets or sets the start time of the operation. - /// - /// The start time of the operation. - public System.DateTimeOffset StartTime { get; set; } - - /// - /// Gets or sets the end time of the operation. - /// - /// The end time of the operation. - public System.DateTimeOffset EndTime { get; set; } -#else - /// - /// Gets or sets the start time of the operation. - /// - /// The start time of the operation. - public DateTime StartTime { get; set; } - - /// - /// Gets or sets the end time of the operation. - /// - /// The end time of the operation. - public DateTime EndTime { get; set; } -#endif - #endregion - - #region Request Results - - private IList requestResults = new List(); - - /// - /// Gets or sets the set of request results that the current operation has created. - /// - /// An object that contains objects that represent the request results created by the current operation. - public IList RequestResults - { - get - { - return this.requestResults; - } - } - - /// - /// Gets the last request result encountered for the operation. - /// - /// A object that represents the last request result. - public RequestResult LastResult - { - get - { - if (this.requestResults == null || this.requestResults.Count == 0) - { - return null; - } - else - { - return this.requestResults[this.requestResults.Count - 1]; - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Properties/AssemblyInfo.cs deleted file mode 100644 index e16d055cb7aa1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Resources; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Common")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Common")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: NeutralResourcesLanguage("en")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueue.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueue.Common.cs deleted file mode 100644 index e371e532e9209..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueue.Common.cs +++ /dev/null @@ -1,256 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// This class represents a queue in the Windows Azure Queue service. - /// - [SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Justification = "Reviewed.")] - public sealed partial class CloudQueue - { - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the queue. - public CloudQueue(Uri queueAddress) - : this(queueAddress, null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the queue. - /// The account credentials. - public CloudQueue(Uri queueAddress, StorageCredentials credentials) - { - this.ParseQueryAndVerify(queueAddress, credentials); - this.Metadata = new Dictionary(); - this.EncodeMessage = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// The queue name. - /// A client object that specifies the endpoint for the queue service. - internal CloudQueue(string queueName, CloudQueueClient serviceClient) - { - this.Uri = NavigationHelper.AppendPathToUri(serviceClient.BaseUri, queueName); - this.ServiceClient = serviceClient; - this.Name = queueName; - this.Metadata = new Dictionary(); - this.EncodeMessage = true; - } - - /// - /// Gets the service client for the queue. - /// - /// A client object that specifies the endpoint for the queue service. - public CloudQueueClient ServiceClient { get; private set; } - - /// - /// Gets the queue's URI. - /// - /// The absolute URI to the queue. - public Uri Uri { get; private set; } - - /// - /// Gets the name of the queue. - /// - /// The queue's name. - public string Name { get; private set; } - - /// - /// Gets the approximate message count for the queue. - /// - /// The approximate message count. - public int? ApproximateMessageCount { get; private set; } - - /// - /// Gets or sets a value indicating whether to apply base64 encoding when adding or retrieving messages. - /// - /// True to encode messages; otherwise, false. The default value is true. - public bool EncodeMessage { get; set; } - - /// - /// Gets the queue's metadata. - /// - /// The queue's metadata. - public IDictionary Metadata { get; private set; } - - /// - /// Uri for the messages. - /// - private Uri messageRequestAddress; - - /// - /// Gets the Uri for general message operations. - /// - internal Uri GetMessageRequestAddress() - { - if (this.messageRequestAddress == null) - { - this.messageRequestAddress = NavigationHelper.AppendPathToUri(this.Uri, Constants.Messages); - } - - return this.messageRequestAddress; - } - - /// - /// Gets the individual message address. - /// - /// The message id. - /// The URI of the message. - internal Uri GetIndividualMessageAddress(string messageId) - { - Uri individualMessageUri = NavigationHelper.AppendPathToUri(this.GetMessageRequestAddress(), messageId); - - return individualMessageUri; - } - - /// - /// Parse URI for SAS (Shared Access Signature) information. - /// - /// The complete Uri. - /// The credentials to use. - private void ParseQueryAndVerify(Uri address, StorageCredentials credentials) - { - StorageCredentials parsedCredentials; - this.Uri = NavigationHelper.ParseQueueTableQueryAndVerify(address, out parsedCredentials); - - if ((parsedCredentials != null) && (credentials != null) && !parsedCredentials.Equals(credentials)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleCredentialsProvided); - throw new ArgumentException(error); - } - - this.ServiceClient = new CloudQueueClient(NavigationHelper.GetServiceClientBaseAddress(this.Uri, null), credentials ?? parsedCredentials); - this.Name = NavigationHelper.GetQueueNameFromUri(this.Uri, this.ServiceClient.UsePathStyleUris); - } - - /// - /// Returns the canonical name for shared access. - /// - /// The canonical name. - private string GetCanonicalName() - { - if (this.ServiceClient.UsePathStyleUris) - { - return this.Uri.AbsolutePath; - } - else - { - return NavigationHelper.GetCanonicalPathFromCreds(this.ServiceClient.Credentials, this.Uri.AbsolutePath); - } - } - - /// - /// Selects the get message response. - /// - /// The protocol message. - /// The parsed message. - private CloudQueueMessage SelectGetMessageResponse(QueueMessage protocolMessage) - { - CloudQueueMessage message = this.SelectPeekMessageResponse(protocolMessage); - message.PopReceipt = protocolMessage.PopReceipt; - - if (protocolMessage.NextVisibleTime.HasValue) - { - message.NextVisibleTime = protocolMessage.NextVisibleTime.Value; - } - - return message; - } - - /// - /// Selects the peek message response. - /// - /// The protocol message. - /// The parsed message. - private CloudQueueMessage SelectPeekMessageResponse(QueueMessage protocolMessage) - { - CloudQueueMessage message = null; - if (this.EncodeMessage) - { - // if EncodeMessage is true, we assume the string returned from server is Base64 encoding of original message; - // if this is not true, exception will likely be thrown. - // it is user's responsibility to make sure EncodeMessage setting matches the queue that is being read. - message = new CloudQueueMessage(protocolMessage.Text, true); - } - else - { - message = new CloudQueueMessage(protocolMessage.Text); - } - - message.Id = protocolMessage.Id; - message.InsertionTime = protocolMessage.InsertionTime; - message.ExpirationTime = protocolMessage.ExpirationTime; - message.DequeueCount = protocolMessage.DequeueCount; - - // PopReceipt and TimeNextVisible are not returned during peek - return message; - } - - /// - /// Returns a shared access signature for the queue. - /// - /// The access policy for the shared access signature. - /// A queue-level access policy. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - public string GetSharedAccessSignature(SharedAccessQueuePolicy policy, string accessPolicyIdentifier) - { - if (!this.ServiceClient.Credentials.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASWithoutAccountKey); - throw new InvalidOperationException(errorMessage); - } - - string resourceName = this.GetCanonicalName(); - StorageAccountKey accountKey = this.ServiceClient.Credentials.Key; - - string signature = SharedAccessSignatureHelper.GetSharedAccessSignatureHashImpl( - policy, - accessPolicyIdentifier, - resourceName, - accountKey.KeyValue); - - string accountKeyName = accountKey.KeyName; - - UriQueryBuilder builder = SharedAccessSignatureHelper.GetSharedAccessSignatureImpl( - policy, - accessPolicyIdentifier, - signature, - accountKeyName); - - return builder.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueClient.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueClient.Common.cs deleted file mode 100644 index 9429c186b5e14..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueClient.Common.cs +++ /dev/null @@ -1,206 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Globalization; - - /// - /// Provides a client-side logical representation of the Windows Azure Queue service. This client is used to configure and execute requests against the Queue service. - /// - /// The service client encapsulates the base URI for the Queue service. If the service client will be used for authenticated access, it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudQueueClient - { - /// - /// The default server and client timeout interval. - /// - private TimeSpan? timeout; - - /// - /// Max execution time across all potential retries. - /// - private TimeSpan? maximumExecutionTime; - - private AuthenticationScheme authenticationScheme; - - /// - /// Initializes a new instance of the class using the specified queue service endpoint - /// and anonymous credentials. - /// - /// The queue service endpoint to use to create the client. - public CloudQueueClient(Uri baseUri) - : this(baseUri, null) - { - } - - /// - /// Initializes a new instance of the class using the specified queue service endpoint - /// and account credentials. - /// - /// The queue service endpoint to use to create the client. - /// The account credentials. - public CloudQueueClient(Uri baseUri, StorageCredentials credentials) - : this(null, baseUri, credentials) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// True to use path style Uris. - /// The queue service endpoint to use to create the client. - /// The account credentials. - internal CloudQueueClient(bool? usePathStyleUris, Uri baseUri, StorageCredentials credentials) - { - CommonUtility.AssertNotNull("baseUri", baseUri); - - if (credentials == null) - { - credentials = new StorageCredentials(); - } - - if (baseUri == null) - { - throw new ArgumentNullException("baseUri"); - } - - if (!baseUri.IsAbsoluteUri) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.RelativeAddressNotPermitted, baseUri.ToString()); - throw new ArgumentException(errorMessage, "baseUri"); - } - - this.BaseUri = baseUri; - this.Credentials = credentials; - this.RetryPolicy = new ExponentialRetry(); - this.ServerTimeout = Constants.DefaultServerSideTimeout; - this.AuthenticationScheme = AuthenticationScheme.SharedKey; - - if (usePathStyleUris.HasValue) - { - this.UsePathStyleUris = usePathStyleUris.Value; - } - else - { - // Automatically decide whether to use host style uri or path style uri - this.UsePathStyleUris = CommonUtility.UsePathStyleAddressing(this.BaseUri); - } - } - - /// - /// Gets or sets a buffer manager that implements the interface, - /// specifying a buffer pool for use with operations against the Queue service client. - /// - public IBufferManager BufferManager { get; set; } - - /// - /// Gets the account credentials used to create the queue service client. - /// - /// The account credentials. - public StorageCredentials Credentials { get; private set; } - - /// - /// Gets the base URI for the Queue service client. - /// - /// The base URI used to construct the Queue service client. - public Uri BaseUri { get; private set; } - - /// - /// Gets or sets the default retry policy for requests made via the Queue service client. - /// - /// The retry policy. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the default server and client timeout for requests made via the Queue service client. - /// - /// The server and client timeout interval. - public TimeSpan? ServerTimeout - { - get - { - return this.timeout; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.timeout = value; - } - } - - /// - /// Gets or sets the maximum execution time across all potential retries. - /// - /// The maximum execution time across all potential retries. - public TimeSpan? MaximumExecutionTime - { - get - { - return this.maximumExecutionTime; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.maximumExecutionTime = value; - } - } - - /// - /// Gets a value indicating whether the service client is used with Path style or Host style. - /// - /// Is true if use path style uris; otherwise, false. - internal bool UsePathStyleUris { get; private set; } - - /// - /// Returns a reference to a object with the specified name. - /// - /// The name of the queue, or an absolute URI to the queue. - /// A reference to a queue. - public CloudQueue GetQueueReference(string queueName) - { - CommonUtility.AssertNotNullOrEmpty("queueName", queueName); - return new CloudQueue(queueName, this); - } - - private ICanonicalizer GetCanonicalizer() - { - if (this.AuthenticationScheme == AuthenticationScheme.SharedKeyLite) - { - return SharedKeyLiteCanonicalizer.Instance; - } - - return SharedKeyCanonicalizer.Instance; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueMessage.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueMessage.Common.cs deleted file mode 100644 index c689edcd36786..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/CloudQueueMessage.Common.cs +++ /dev/null @@ -1,298 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Text; - - /// - /// Represents a message in the Windows Azure Queue service. - /// - public sealed partial class CloudQueueMessage - { - /// - /// The maximum message size in bytes. - /// - private const long MaximumMessageSize = 64 * Constants.KB; - - /// - /// Gets the maximum message size in bytes. - /// - /// The maximum message size in bytes. - public static long MaxMessageSize - { - get - { - return MaximumMessageSize; - } - } - - /// - /// The maximum amount of time a message is kept in the queue. - /// - private static readonly TimeSpan MaximumTimeToLive = TimeSpan.FromDays(7); - - /// - /// Gets the maximum amount of time a message is kept in the queue. - /// - /// The maximum amount of time a message is kept in the queue. - public static TimeSpan MaxTimeToLive - { - get - { - return MaximumTimeToLive; - } - } - - /// - /// The maximum number of messages that can be peeked at a time. - /// - private const int MaximumNumberOfMessagesToPeek = 32; - - /// - /// Gets the maximum number of messages that can be peeked at a time. - /// - /// The maximum number of messages that can be peeked at a time. - public static int MaxNumberOfMessagesToPeek - { - get - { - return MaximumNumberOfMessagesToPeek; - } - } - - /// - /// Custom UTF8Encoder to throw exception in case of invalid bytes. - /// - private static UTF8Encoding utf8Encoder = new UTF8Encoding(false, true); - - /// - /// Initializes a new instance of the class with the given byte array. - /// - internal CloudQueueMessage() - { - } - - /// - /// Initializes a new instance of the class with the given string. - /// - /// The content of the message as a string of text. - public CloudQueueMessage(string content) - { - this.SetMessageContent(content); - - // At this point, without knowing whether or not the message will be Base64 encoded, we can't fully validate the message size. - // So we leave it to CloudQueue so that we have a central place for this logic. - } - - /// - /// Initializes a new instance of the class with the given message ID and pop receipt. - /// - /// The message ID. - /// The pop receipt token. - public CloudQueueMessage(string messageId, string popReceipt) - { - this.Id = messageId; - this.PopReceipt = popReceipt; - } - - /// - /// Initializes a new instance of the class with the given Base64 encoded string. - /// This method is only used internally. - /// - /// The text string. - /// Whether the string is Base64 encoded. - internal CloudQueueMessage(string content, bool isBase64Encoded) - { - if (content == null) - { - content = string.Empty; - } - - this.RawString = content; - this.MessageType = isBase64Encoded ? QueueMessageType.Base64Encoded : QueueMessageType.RawString; - } - - /// - /// Gets the content of the message as a byte array. - /// - /// The content of the message as a byte array. - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Reviewed.")] - public byte[] AsBytes - { - get - { - if (this.MessageType == QueueMessageType.RawString) - { - return Encoding.UTF8.GetBytes(this.RawString); - } - else - { - return Convert.FromBase64String(this.RawString); - } - } - } - - /// - /// Gets the message ID. - /// - /// The message ID. - public string Id { get; internal set; } - - /// - /// Gets the message's pop receipt. - /// - /// The pop receipt value. - public string PopReceipt { get; internal set; } - - /// - /// Gets the time that the message was added to the queue. - /// - /// The time that the message was added to the queue. - public DateTimeOffset? InsertionTime { get; internal set; } - - /// - /// Gets the time that the message expires. - /// - /// The time that the message expires. - public DateTimeOffset? ExpirationTime { get; internal set; } - - /// - /// Gets the time that the message will next be visible. - /// - /// The time that the message will next be visible. - public DateTimeOffset? NextVisibleTime { get; internal set; } - - /// - /// Gets the content of the message, as a string. - /// - /// The message content. - public string AsString - { - get - { - if (this.MessageType == QueueMessageType.RawString) - { - return this.RawString; - } - else - { - byte[] messageData = Convert.FromBase64String(this.RawString); - return utf8Encoder.GetString(messageData, 0, messageData.Length); - } - } - } - - /// - /// Gets the number of times this message has been dequeued. - /// - /// The number of times this message has been dequeued. - public int DequeueCount { get; internal set; } - - /// - /// Gets message type that indicates if the RawString is the original message string or Base64 encoding of the original binary data. - /// - internal QueueMessageType MessageType { get; private set; } - - /// - /// Gets or sets the original message string or Base64 encoding of the original binary data. - /// - /// The original message string. - internal string RawString { get; set; } - - /// - /// Gets the content of the message for transfer (internal use only). - /// - /// Indicates if the message should be encoded. - /// The message content as a string. - internal string GetMessageContentForTransfer(bool shouldEncodeMessage) - { - if (!shouldEncodeMessage && this.MessageType == QueueMessageType.Base64Encoded) - { - throw new ArgumentException(SR.BinaryMessageShouldUseBase64Encoding); - } - - string outgoingMessageString = null; - if (this.MessageType == QueueMessageType.RawString) - { - if (shouldEncodeMessage) - { - outgoingMessageString = Convert.ToBase64String(this.AsBytes); - - // the size of Base64 encoded string is the number of bytes this message will take up on server. - if (outgoingMessageString.Length > CloudQueueMessage.MaxMessageSize) - { - throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - SR.MessageTooLarge, - CloudQueueMessage.MaxMessageSize)); - } - } - else - { - outgoingMessageString = this.RawString; - - // we need to calculate the size of its UTF8 byte array, as that will be the storage usage on server. - if (Encoding.UTF8.GetBytes(outgoingMessageString).Length > CloudQueueMessage.MaxMessageSize) - { - throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - SR.MessageTooLarge, - CloudQueueMessage.MaxMessageSize)); - } - } - } - else - { - // at this point, this.EncodeMessage must be true - outgoingMessageString = this.RawString; - - // the size of Base64 encoded string is the number of bytes this message will take up on server. - if (outgoingMessageString.Length > CloudQueueMessage.MaxMessageSize) - { - throw new ArgumentException(string.Format( - CultureInfo.InvariantCulture, - SR.MessageTooLarge, - CloudQueueMessage.MaxMessageSize)); - } - } - - return outgoingMessageString; - } - - /// - /// Sets the content of this message. - /// - /// The new message content. - public void SetMessageContent(string content) - { - if (content == null) - { - // Protocol will return null for empty content - content = string.Empty; - } - - this.RawString = content; - this.MessageType = QueueMessageType.RawString; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/MessageUpdateFields.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/MessageUpdateFields.cs deleted file mode 100644 index 167b2525ff913..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/MessageUpdateFields.cs +++ /dev/null @@ -1,38 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using System; - - /// - /// Enumeration controlling the options for updating queue messages. - /// - [Flags] - public enum MessageUpdateFields - { - /// - /// Update the message visibility timeout. - /// - Visibility = 0x1, - - /// - /// Update the message content. - /// - Content = 0x2 - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/GetMessagesResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/GetMessagesResponse.cs deleted file mode 100644 index 3cd3464970cdc..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/GetMessagesResponse.cs +++ /dev/null @@ -1,188 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - - /// - /// Provides methods for parsing the response from an operation to get messages from a queue. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class GetMessagesResponse : ResponseParsingBase - { - /// - /// Initializes a new instance of the class. - /// - /// The stream of messages to parse. - public GetMessagesResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets an enumerable collection of objects from the response. - /// - /// An enumerable collection of objects. - public IEnumerable Messages - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Parses a message entry in a queue get messages response. - /// - /// Message entry - private QueueMessage ParseMessageEntry() - { - QueueMessage message = null; - string id = null; - string popReceipt = null; - DateTime? insertionTime = null; - DateTime? expirationTime = null; - DateTime? timeNextVisible = null; - string text = null; - int dequeueCount = 0; - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.MessageIdElement: - id = reader.ReadElementContentAsString(); - break; - - case Constants.PopReceiptElement: - popReceipt = reader.ReadElementContentAsString(); - break; - - case Constants.InsertionTimeElement: - insertionTime = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.ExpirationTimeElement: - expirationTime = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.TimeNextVisibleElement: - timeNextVisible = reader.ReadElementContentAsString().ToUTCTime(); - break; - - case Constants.MessageTextElement: - text = reader.ReadElementContentAsString(); - break; - - case Constants.DequeueCountElement: - dequeueCount = reader.ReadElementContentAsInt(); - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - message = new QueueMessage(); - message.Text = text; - message.Id = id; - message.PopReceipt = popReceipt; - message.DequeueCount = dequeueCount; - - if (insertionTime != null) - { - message.InsertionTime = (DateTime)insertionTime; - } - - if (expirationTime != null) - { - message.ExpirationTime = (DateTime)expirationTime; - } - - if (timeNextVisible != null) - { - message.NextVisibleTime = (DateTime)timeNextVisible; - } - - return message; - } - - /// - /// Parses the XML response returned by an operation to get messages from a queue. - /// - /// An enumerable collection of objects. - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.MessagesElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (this.reader.Name) - { - case Constants.MessageElement: - while (this.reader.IsStartElement()) - { - yield return this.ParseMessageEntry(); - } - - break; - - default: - reader.Skip(); - break; - } - } - } - - this.allObjectsParsed = true; - this.reader.ReadEndElement(); - } - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/ListQueuesResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/ListQueuesResponse.cs deleted file mode 100644 index e06aa728356e4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/ListQueuesResponse.cs +++ /dev/null @@ -1,272 +0,0 @@ -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - - /// - /// Provides methods for parsing the response from a queue listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class ListQueuesResponse : ResponseParsingBase - { - /// - /// Stores the container prefix. - /// - private string prefix; - - /// - /// Signals when the container prefix can be consumed. - /// - private bool prefixConsumable; - - /// - /// Stores the marker. - /// - private string marker; - - /// - /// Signals when the marker can be consumed. - /// - private bool markerConsumable; - - /// - /// Stores the max results. - /// - private int maxResults; - - /// - /// Signals when the max results can be consumed. - /// - private bool maxResultsConsumable; - - /// - /// Stores the next marker. - /// - private string nextMarker; - - /// - /// Signals when the next marker can be consumed. - /// - private bool nextMarkerConsumable; - - /// - /// Initializes a new instance of the class. - /// - /// The stream to be parsed. - public ListQueuesResponse(Stream stream) - : base(stream) - { - } - - /// - /// Gets the listing context from the XML response. - /// - /// A set of parameters for the listing operation. - public ListingContext ListingContext - { - get - { - // Force a parsing in order - ListingContext listingContext = new ListingContext(this.Prefix, this.MaxResults); - listingContext.Marker = this.NextMarker; - return listingContext; - } - } - - /// - /// Gets an enumerable collection of objects from the response. - /// - /// An enumerable collection of objects. - public IEnumerable Queues - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Gets the Prefix value provided for the listing operation from the XML response. - /// - /// The Prefix value. - public string Prefix - { - get - { - this.Variable(ref this.prefixConsumable); - - return this.prefix; - } - } - - /// - /// Gets the Marker value provided for the listing operation from the XML response. - /// - /// The Marker value. - public string Marker - { - get - { - this.Variable(ref this.markerConsumable); - - return this.marker; - } - } - - /// - /// Gets the MaxResults value provided for the listing operation from the XML response. - /// - /// The MaxResults value. - public int MaxResults - { - get - { - this.Variable(ref this.maxResultsConsumable); - - return this.maxResults; - } - } - - /// - /// Gets the NextMarker value from the XML response, if the listing was not complete. - /// - /// The NextMarker value. - public string NextMarker - { - get - { - this.Variable(ref this.nextMarkerConsumable); - - return this.nextMarker; - } - } - - /// - /// Parses a queue entry in a queue listing response. - /// - /// Queue listing entry - private QueueEntry ParseQueueEntry() - { - Uri uri = null; - string name = null; - IDictionary metadata = null; - - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.UrlElement: - string url = reader.ReadElementContentAsString(); - Uri.TryCreate(url, UriKind.Absolute, out uri); - break; - - case Constants.NameElement: - name = reader.ReadElementContentAsString(); - break; - - case Constants.MetadataElement: - metadata = Response.ParseMetadata(this.reader); - break; - - default: - this.reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - if (metadata == null) - { - metadata = new Dictionary(); - } - - return new QueueEntry(name, uri, metadata); - } - - /// - /// Parses the response XML for a queue listing operation. - /// - /// An enumerable collection of objects. - protected override IEnumerable ParseXml() - { - if (this.reader.ReadToFollowing(Constants.EnumerationResultsElement)) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - if (this.reader.IsEmptyElement) - { - this.reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.MarkerElement: - this.marker = reader.ReadElementContentAsString(); - this.markerConsumable = true; - yield return null; - break; - - case Constants.NextMarkerElement: - this.nextMarker = reader.ReadElementContentAsString(); - this.nextMarkerConsumable = true; - yield return null; - break; - - case Constants.MaxResultsElement: - this.maxResults = reader.ReadElementContentAsInt(); - this.maxResultsConsumable = true; - yield return null; - break; - - case Constants.PrefixElement: - this.prefix = reader.ReadElementContentAsString(); - this.prefixConsumable = true; - yield return null; - break; - - case Constants.QueuesElement: - this.reader.ReadStartElement(); - while (this.reader.IsStartElement()) - { - yield return this.ParseQueueEntry(); - } - - this.reader.ReadEndElement(); - this.allObjectsParsed = true; - break; - - default: - reader.Skip(); - break; - } - } - } - - this.reader.ReadEndElement(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueAccessPolicyResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueAccessPolicyResponse.cs deleted file mode 100644 index 049c3476113c9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueAccessPolicyResponse.cs +++ /dev/null @@ -1,71 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.IO; - using System.Xml.Linq; - - /// - /// Parses the response XML from an operation to set the access policy for a queue. - /// - internal class QueueAccessPolicyResponse : AccessPolicyResponseBase - { - /// - /// Initializes a new instance of the QueueAccessPolicyResponse class. - /// - /// The stream to be parsed. - internal QueueAccessPolicyResponse(Stream stream) - : base(stream) - { - } - - /// - /// Parses the current element. - /// - /// The shared access policy element to parse. - /// The shared access policy. - protected override SharedAccessQueuePolicy ParseElement(XElement accessPolicyElement) - { - CommonUtility.AssertNotNull("accessPolicyElement", accessPolicyElement); - - SharedAccessQueuePolicy accessPolicy = new SharedAccessQueuePolicy(); - string sharedAccessStartTimeString = (string)accessPolicyElement.Element(Constants.Start); - if (!string.IsNullOrEmpty(sharedAccessStartTimeString)) - { - accessPolicy.SharedAccessStartTime = Uri.UnescapeDataString(sharedAccessStartTimeString).ToUTCTime(); - } - - string sharedAccessExpiryTimeString = (string)accessPolicyElement.Element(Constants.Expiry); - if (!string.IsNullOrEmpty(sharedAccessExpiryTimeString)) - { - accessPolicy.SharedAccessExpiryTime = Uri.UnescapeDataString(sharedAccessExpiryTimeString).ToUTCTime(); - } - - string permissionsString = (string)accessPolicyElement.Element(Constants.Permission); - if (!string.IsNullOrEmpty(permissionsString)) - { - accessPolicy.Permissions = SharedAccessQueuePolicy.PermissionsFromString(permissionsString); - } - - return accessPolicy; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueContinuationToken.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueContinuationToken.cs deleted file mode 100644 index bdef3f745b32d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueContinuationToken.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Xml; - using System.Xml.Schema; - using System.Xml.Serialization; - - /// - /// Represents a continuation token returned by the Queue service. - /// - /// continuation tokens are used in methods that return a object, such as . - [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1001:CommasMustBeSpacedCorrectly", Justification = "Reviewed.")] - public sealed class QueueContinuationToken : IContinuationToken -#if WINDOWS_DESKTOP -, IXmlSerializable -#endif - { - /// - /// Gets or sets the NextMarker for continuing results for CloudQueue enumeration operations. - /// - /// The next marker. - public string NextMarker { get; set; } - -#if WINDOWS_DESKTOP - /// - /// Gets an XML representation of an object. - /// - /// - /// An that describes the XML representation of the object that is produced by the method and consumed by the method. - /// - public XmlSchema GetSchema() - { - return null; - } - - /// - /// Generates a serializable continuation token from its XML representation. - /// - /// The stream from which the continuation token is deserialized. - public void ReadXml(XmlReader reader) - { - CommonUtility.AssertNotNull("reader", reader); - - reader.MoveToContent(); - - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - reader.ReadStartElement(); - while (reader.IsStartElement()) - { - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.ContinuationConstants.VersionElement: - string version = reader.ReadElementContentAsString(); - if (version != Constants.ContinuationConstants.CurrentVersion) - { - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, version)); - } - - break; - - case Constants.ContinuationConstants.NextMarkerElement: - this.NextMarker = reader.ReadElementContentAsString(); - break; - - case Constants.ContinuationConstants.TypeElement: - string continuationType = reader.ReadElementContentAsString(); - if (Constants.ContinuationConstants.QueueType != continuationType) - { - throw new XmlException(SR.UnexpectedContinuationType); - } - - break; - - default: - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, reader.Name)); - } - } - } - - reader.ReadEndElement(); - } - } - - /// - /// Converts a serializable continuation token into its XML representation. - /// - /// The stream to which the continuation token is serialized. - public void WriteXml(XmlWriter writer) - { - CommonUtility.AssertNotNull("writer", writer); - - writer.WriteStartElement(Constants.ContinuationConstants.ContinuationTopElement); - - writer.WriteElementString(Constants.ContinuationConstants.VersionElement, Constants.ContinuationConstants.CurrentVersion); - - writer.WriteElementString(Constants.ContinuationConstants.TypeElement, Constants.ContinuationConstants.QueueType); - - if (this.NextMarker != null) - { - writer.WriteElementString(Constants.ContinuationConstants.NextMarkerElement, this.NextMarker); - } - - writer.WriteEndElement(); // End ContinuationToken - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueEntry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueEntry.cs deleted file mode 100644 index 18a241bf5b34b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueEntry.cs +++ /dev/null @@ -1,71 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using System; - using System.Collections.Generic; - - /// - /// Represents a queue item returned in the XML response for a queue listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class QueueEntry - { - /// - /// Initializes a new instance of the class. - /// - internal QueueEntry() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the queue. - /// The Uri of the queue. - /// The queue's metadata. - internal QueueEntry(string name, Uri uri, IDictionary metadata) - { - this.Name = name; - this.Uri = uri; - this.Metadata = metadata; - } - - /// - /// Gets the user-defined metadata for the queue. - /// - /// The queue's metadata, as a collection of name-value pairs. - public IDictionary Metadata { get; internal set; } - - /// - /// Gets the name of the queue. - /// - /// The queue's name. - public string Name { get; internal set; } - - /// - /// Gets the queue's URI. - /// - /// The absolute URI to the queue. - public Uri Uri { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueErrorCodeStrings.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueErrorCodeStrings.cs deleted file mode 100644 index 292659ce692f2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueErrorCodeStrings.cs +++ /dev/null @@ -1,80 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - /// - /// Provides error code strings that are specific to the Queue service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class QueueErrorCodeStrings - { - /// - /// Error code that may be returned when the specified queue was not found. - /// - public const string QueueNotFound = "QueueNotFound"; - - /// - /// Error code that may be returned when the specified queue is disabled. - /// - public const string QueueDisabled = "QueueDisabled"; - - /// - /// Error code that may be returned when the specified queue already exists. - /// - public const string QueueAlreadyExists = "QueueAlreadyExists"; - - /// - /// Error code that may be returned when the specified queue is not empty. - /// - public const string QueueNotEmpty = "QueueNotEmpty"; - - /// - /// Error code that may be returned when the specified queue is being deleted. - /// - public const string QueueBeingDeleted = "QueueBeingDeleted"; - - /// - /// Error code that may be returned when the specified pop receipt does not match. - /// - public const string PopReceiptMismatch = "PopReceiptMismatch"; - - /// - /// Error code that may be returned when one or more request parameters are invalid. - /// - public const string InvalidParameter = "InvalidParameter"; - - /// - /// Error code that may be returned when the specified message was not found. - /// - public const string MessageNotFound = "MessageNotFound"; - - /// - /// Error code that may be returned when the specified message is too large. - /// - public const string MessageTooLarge = "MessageTooLarge"; - - /// - /// Error code that may be returned when the specified marker is invalid. - /// - public const string InvalidMarker = "InvalidMarker"; - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueHttpResponseParsers.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueHttpResponseParsers.Common.cs deleted file mode 100644 index 587e494fd0de7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueHttpResponseParsers.Common.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.IO; - -#if WINDOWS_RT - internal -#else - public -#endif - static partial class QueueHttpResponseParsers - { - /// - /// Reads service properties from a stream. - /// - /// The stream from which to read the service properties. - /// The service properties stored in the stream. - public static ServiceProperties ReadServiceProperties(Stream inputStream) - { - return HttpResponseParsers.ReadServiceProperties(inputStream); - } - - /// - /// Reads the share access policies from a stream in XML. - /// - /// The stream of XML policies. - /// The permissions object to which the policies are to be written. - public static void ReadSharedAccessIdentifiers(Stream inputStream, QueuePermissions permissions) - { - CommonUtility.AssertNotNull("permissions", permissions); - - Response.ReadSharedAccessIdentifiers(permissions.SharedAccessPolicies, new QueueAccessPolicyResponse(inputStream)); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingContext.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingContext.cs deleted file mode 100644 index 44ff634dd57b0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingContext.cs +++ /dev/null @@ -1,51 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - /// - /// Provides a set of parameters for a queue listing operation. - /// -#if WINDOWS_RT - internal -#else - public -#endif - sealed class QueueListingContext : ListingContext - { - /// - /// Initializes a new instance of the class. - /// - /// The queue prefix. - /// The maximum number of results to return. - /// The include parameter. - public QueueListingContext(string prefix, int? maxResults, QueueListingDetails include) - : base(prefix, maxResults) - { - this.Include = include; - } - - /// - /// Gets or sets the details for the listing operation, which indicates the types of data to include in the - /// response. - /// - /// The details to include in the listing operation. - public QueueListingDetails Include { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingDetails.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingDetails.cs deleted file mode 100644 index 48bc23f60906f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueListingDetails.cs +++ /dev/null @@ -1,43 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using System; - - /// - /// Specifies which details to include when listing the queues in this storage account. - /// - [Flags] - public enum QueueListingDetails - { - /// - /// No additional details. - /// - None = 0x0, - - /// - /// Retrieve queue metadata. - /// - Metadata = 0x1, - - /// - /// Retrieve all available details. - /// - All = 0x1 - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueMessage.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueMessage.cs deleted file mode 100644 index 87a024d63bd18..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueMessage.cs +++ /dev/null @@ -1,80 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using System; - - /// - /// Represents a message retrieved from a queue. - /// -#if !WINDOWS_RT - public class QueueMessage -#else - internal class QueueMessage -#endif - { - /// - /// Initializes a new instance of the class. - /// - internal QueueMessage() - { - } - - /// - /// Gets the message expiration time. - /// - /// The message expiration time. - public DateTimeOffset? ExpirationTime { get; internal set; } - - /// - /// Gets the message ID. - /// - /// The message ID. - public string Id { get; internal set; } - - /// - /// Gets the time the message was added to the queue. - /// - /// The message insertion time. - public DateTimeOffset? InsertionTime { get; internal set; } - - /// - /// Gets the time the message is next visible. - /// - /// The time the message is next visible. - public DateTimeOffset? NextVisibleTime { get; internal set; } - - /// - /// Gets the pop receipt for the message. - /// - /// The message's pop receipt. - public string PopReceipt { get; internal set; } - - /// - /// Gets the text of the message. - /// - /// The message text. - public string Text { get; internal set; } - - /// - /// Gets the number of times this message has been dequeued. - /// - /// The dequeue count. - public int DequeueCount { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueuePermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueuePermissions.cs deleted file mode 100644 index 35ef82ff97483..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueuePermissions.cs +++ /dev/null @@ -1,39 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - /// - /// Represents the permissions for a queue. - /// - public sealed class QueuePermissions - { - /// - /// Initializes a new instance of the class. - /// - public QueuePermissions() - { - this.SharedAccessPolicies = new SharedAccessQueuePolicies(); - } - - /// - /// Gets the set of shared access policies for the queue. - /// - /// The set of shared access policies for the queue. - public SharedAccessQueuePolicies SharedAccessPolicies { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueRequest.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueRequest.cs deleted file mode 100644 index 78e1e1fe2e7f4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/Protocol/QueueRequest.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.IO; - using System.Text; - using System.Xml; - - /// - /// Provides a set of helper methods for constructing a request against the Queue service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class QueueRequest - { - /// - /// Writes a collection of shared access policies to the specified stream in XML format. - /// - /// A collection of shared access policies. - /// An output stream. - public static void WriteSharedAccessIdentifiers(SharedAccessQueuePolicies sharedAccessPolicies, Stream outputStream) - { - Request.WriteSharedAccessIdentifiers( - sharedAccessPolicies, - outputStream, - (policy, writer) => - { - writer.WriteElementString( - Constants.Start, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessStartTime)); - writer.WriteElementString( - Constants.Expiry, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessExpiryTime)); - writer.WriteElementString( - Constants.Permission, - SharedAccessQueuePolicy.PermissionsToString(policy.Permissions)); - }); - } - - /// - /// Writes a message to the specified stream in XML format. - /// - /// The message body. - /// An output stream. - internal static void WriteMessageContent(string messageContent, Stream outputStream) - { - CommonUtility.AssertNotNull("outputStream", outputStream); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = Encoding.UTF8; - settings.NewLineHandling = NewLineHandling.Entitize; - - using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) - { - writer.WriteStartElement(Constants.MessageElement); - writer.WriteElementString(Constants.MessageTextElement, messageContent); - writer.WriteEndDocument(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueMessageType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueMessageType.cs deleted file mode 100644 index 5e00943fb7077..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueMessageType.cs +++ /dev/null @@ -1,36 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - /// - /// Enum for Queue message type. - /// Internal use only. - /// - internal enum QueueMessageType - { - /// - /// Indicates the message object stores the raw text string. - /// - RawString, - - /// - /// Indicates the message object stores the Base64-Encoded representation of the raw data. - /// - Base64Encoded - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueRequestOptions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueRequestOptions.cs deleted file mode 100644 index 62b55f9f01e52..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueRequestOptions.cs +++ /dev/null @@ -1,89 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using System; - - /// - /// Represents a set of timeout and retry policy options that may be specified for a request against the Queue service. - /// - public sealed class QueueRequestOptions : IRequestOptions - { - /// - /// Initializes a new instance of the class. - /// - public QueueRequestOptions() - { - } - - /// - /// Clones an instance of QueueRequestOptions so that we can apply defaults. - /// - /// QueueRequestOptions instance to be cloned. - internal QueueRequestOptions(QueueRequestOptions other) - : this() - { - if (other != null) - { - this.RetryPolicy = other.RetryPolicy; - this.ServerTimeout = other.ServerTimeout; - this.MaximumExecutionTime = other.MaximumExecutionTime; - this.OperationExpiryTime = other.OperationExpiryTime; - } - } - - internal static QueueRequestOptions ApplyDefaults(QueueRequestOptions options, CloudQueueClient serviceClient) - { - QueueRequestOptions modifiedOptions = new QueueRequestOptions(options); - modifiedOptions.RetryPolicy = modifiedOptions.RetryPolicy ?? serviceClient.RetryPolicy; - modifiedOptions.ServerTimeout = modifiedOptions.ServerTimeout ?? serviceClient.ServerTimeout; - modifiedOptions.MaximumExecutionTime = modifiedOptions.MaximumExecutionTime ?? serviceClient.MaximumExecutionTime; - - if (!modifiedOptions.OperationExpiryTime.HasValue && modifiedOptions.MaximumExecutionTime.HasValue) - { - modifiedOptions.OperationExpiryTime = DateTime.Now + modifiedOptions.MaximumExecutionTime.Value; - } - - return modifiedOptions; - } - - /// - /// Gets or sets the absolute expiry time across all potential retries for the request. - /// - internal DateTime? OperationExpiryTime { get; set; } - - /// - /// Gets or sets the retry policy for the request. - /// - /// The retry policy delegate. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the server timeout for the request. - /// - /// The client and server timeout interval for the request. - public TimeSpan? ServerTimeout { get; set; } - - /// - /// Gets or sets the maximum execution time across all potential retries for the request. - /// - /// A representing the maximum execution time for retries for the request. - public TimeSpan? MaximumExecutionTime { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueResultSegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueResultSegment.cs deleted file mode 100644 index 019778453c647..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/QueueResultSegment.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using System.Collections.Generic; - - /// - /// Represents a segment of results, with continuation information for pagination scenarios. - /// - public sealed class QueueResultSegment - { - internal QueueResultSegment(IEnumerable queues, QueueContinuationToken continuationToken) - { - this.Results = queues; - this.ContinuationToken = continuationToken; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - public IEnumerable Results { get; private set; } - - /// - /// Gets the continuation token used to retrieve the next segment of results. Returns null if there are no more results. - /// - /// The continuation token. - public QueueContinuationToken ContinuationToken { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePermissions.cs deleted file mode 100644 index d477920fbd03b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePermissions.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using System; - - /// - /// Specifies the set of possible permissions for a shared access queue policy. - /// - [Flags] - public enum SharedAccessQueuePermissions - { - /// - /// No shared access granted. - /// - None = 0x0, - - /// - /// Permission to peek messages and get queue metadata granted. - /// - Read = 0x1, - - /// - /// Permission to add messages granted. - /// - Add = 0x2, - - /// - /// Permissions to update messages granted. - /// - Update = 0x4, - - /// - /// Permission to get and delete messages granted. - /// - ProcessMessages = 0x8 - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicies.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicies.cs deleted file mode 100644 index 065ed31c84323..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicies.cs +++ /dev/null @@ -1,234 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents the collection of shared access policies defined for a queue. - /// - [SuppressMessage( - "Microsoft.Naming", - "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Public APIs should not expose base collection types.")] - public sealed class SharedAccessQueuePolicies : IDictionary - { - private Dictionary policies = - new Dictionary(); - - /// - /// Adds the specified key and value to the collection of shared access policies. - /// - /// The key of the value to add. - /// The value to add the collection of shared access policies. - public void Add(string key, SharedAccessQueuePolicy value) - { - this.policies.Add(key, value); - } - - /// - /// Determines whether the collection of shared access policies contains the specified key. - /// - /// The key to locate in the collection of shared access policies. - /// true if the collection of shared access policies contains an element with the specified key; otherwise, false. - public bool ContainsKey(string key) - { - return this.policies.ContainsKey(key); - } - - /// - /// Gets a collection containing the keys in the shared access policies collection. - /// - /// A collection containing the keys in the of shared access policies collection. - public ICollection Keys - { - get - { - return this.policies.Keys; - } - } - - /// - /// Removes the value with the specified key from the shared access policies collection. - /// - /// The key of the item to remove. - /// true if the element is successfully found and removed; otherwise, false. This method returns false if the key is not found. - public bool Remove(string key) - { - return this.policies.Remove(key); - } - - /// - /// Gets the item associated with the specified key. - /// - /// The key of the value to get. - /// The item to get. - /// The item associated with the specified key, if the key is found; otherwise, the default value for the type. - public bool TryGetValue(string key, out SharedAccessQueuePolicy value) - { - return this.policies.TryGetValue(key, out value); - } - - /// - /// Gets a collection containing the values in the shared access policies collection. - /// - /// A collection of items in the shared access policies collection. - public ICollection Values - { - get - { - return this.policies.Values; - } - } - - /// - /// Gets or sets the item associated with the specified key. - /// - /// The key of the value to get or set. - /// The item associated with the specified key, or null if key is not in the shared access policies collection. - public SharedAccessQueuePolicy this[string key] - { - get - { - return this.policies[key]; - } - - set - { - this.policies[key] = value; - } - } - - /// - /// Adds the specified key/ value, stored in a , to the collection of shared access policies. - /// - /// The object, containing a key/ value pair, to add to the shared access policies collection. - public void Add(KeyValuePair item) - { - this.Add(item.Key, item.Value); - } - - /// - /// Removes all keys and values from the shared access collection. - /// - public void Clear() - { - this.policies.Clear(); - } - - /// - /// Determines whether the collection of shared access policies contains the key and value in the specified object. - /// - /// A object containing the key and value to search for. - /// true if the shared access policies collection contains the specified key/value; otherwise, false. - public bool Contains(KeyValuePair item) - { - SharedAccessQueuePolicy storedItem; - if (this.TryGetValue(item.Key, out storedItem)) - { - if (string.Equals( - SharedAccessQueuePolicy.PermissionsToString(item.Value.Permissions), - SharedAccessQueuePolicy.PermissionsToString(storedItem.Permissions), - StringComparison.Ordinal)) - { - return true; - } - } - - return false; - } - - /// - /// Copies each key/ value pair in the shared access policies collection to a compatible one-dimensional array, starting at the specified index of the target array. - /// - /// The one-dimensional array of objects that is the destination of the elements copied from the shared access policies collection. - /// The zero-based index in at which copying begins. - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - CommonUtility.AssertNotNull("array", array); - - foreach (KeyValuePair item in this.policies) - { - array[arrayIndex++] = item; - } - } - - /// - /// Gets the number of key/ value pairs contained in the shared access policies collection. - /// - /// The number of key/ value pairs contained in the shared access policies collection. - public int Count - { - get - { - return this.policies.Count; - } - } - - /// - /// Gets a value indicating whether the collection of shared access policies is read-only. - /// - /// true if the collection of shared access policies is read-only; otherwise, false. - public bool IsReadOnly - { - get - { - return false; - } - } - - /// - /// Removes the value, specified in the object, from the shared access policies collection. - /// - /// The object, containing a key and value, to remove from the shared access policies collection. - /// true if the item was successfully removed; otherwise, false. - public bool Remove(KeyValuePair item) - { - if (this.Contains(item)) - { - return this.Remove(item.Key); - } - else - { - return false; - } - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An of type . - public IEnumerator> GetEnumerator() - { - return this.policies.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An object that can be used to iterate through the collection of shared access policies. - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - System.Collections.IEnumerable enumerable = this.policies; - return enumerable.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicy.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicy.cs deleted file mode 100644 index 3e0c84423c1da..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Queue/SharedAccessQueuePolicy.cs +++ /dev/null @@ -1,132 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Text; - - /// - /// Represents a shared access policy for a queue, which specifies the start time, expiry time, - /// and permissions for a shared access signature. - /// - public sealed class SharedAccessQueuePolicy - { - /// - /// Initializes a new instance of the SharedAccessQueuePolicy class. - /// - public SharedAccessQueuePolicy() - { - } - - /// - /// Gets or sets the start time for a shared access signature associated with this shared access policy. - /// - /// The shared access start time. - public DateTimeOffset? SharedAccessStartTime { get; set; } - - /// - /// Gets or sets the expiry time for a shared access signature associated with this shared access policy. - /// - /// The shared access expiry time. - public DateTimeOffset? SharedAccessExpiryTime { get; set; } - - /// - /// Gets or sets the permissions for a shared access signature associated with this shared access policy. - /// - /// The permissions. - public SharedAccessQueuePermissions Permissions { get; set; } - - /// - /// Converts the permissions specified for the shared access policy to a string. - /// - /// The shared access permissions. - /// The shared access permissions in string format. - public static string PermissionsToString(SharedAccessQueuePermissions permissions) - { - // The queue service supports a fixed order => raup - StringBuilder builder = new StringBuilder(); - if ((permissions & SharedAccessQueuePermissions.Read) == SharedAccessQueuePermissions.Read) - { - builder.Append("r"); - } - - if ((permissions & SharedAccessQueuePermissions.Add) == SharedAccessQueuePermissions.Add) - { - builder.Append("a"); - } - - if ((permissions & SharedAccessQueuePermissions.Update) == SharedAccessQueuePermissions.Update) - { - builder.Append("u"); - } - - if ((permissions & SharedAccessQueuePermissions.ProcessMessages) == SharedAccessQueuePermissions.ProcessMessages) - { - builder.Append("p"); - } - - return builder.ToString(); - } - - /// - /// Constructs a object from a permissions string. - /// - /// The shared access permissions in string format. - /// A set of shared access permissions. - public static SharedAccessQueuePermissions PermissionsFromString(string input) - { - CommonUtility.AssertNotNull("input", input); - - SharedAccessQueuePermissions permissions = 0; - - foreach (char c in input) - { - switch (c) - { - case 'r': - permissions |= SharedAccessQueuePermissions.Read; - break; - - case 'p': - permissions |= SharedAccessQueuePermissions.ProcessMessages; - break; - - case 'a': - permissions |= SharedAccessQueuePermissions.Add; - break; - - case 'u': - permissions |= SharedAccessQueuePermissions.Update; - break; - - default: - throw new ArgumentOutOfRangeException("input"); - } - } - - // Incase we ever change none to be something other than 0 - if (permissions == 0) - { - permissions |= SharedAccessQueuePermissions.None; - } - - return permissions; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RequestEventArgs.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RequestEventArgs.cs deleted file mode 100644 index d1701754bcbeb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RequestEventArgs.cs +++ /dev/null @@ -1,68 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - -#if !WINDOWS_RT - using System.Net; -#endif - - /// - /// Provides information and event data that is associated with a request event. - /// - public sealed class RequestEventArgs -#if !WINDOWS_RT - : EventArgs -#endif - { - /// - /// Initializes a new instance of the class by using the specified parameter. - /// - /// The object. - public RequestEventArgs(RequestResult res) -#if !WINDOWS_RT - : base() -#endif - { - this.RequestInformation = res; - } - - /// - /// Gets the request information associated with this event. - /// - /// The request information associated with this event. - public RequestResult RequestInformation { get; internal set; } - -#if WINDOWS_RT - public Uri RequestUri { get; internal set; } -#else - /// - /// Gets the HTTP request associated with this event. - /// - /// The HTTP request associated with this event. - public HttpWebRequest Request { get; internal set; } - - /// - /// Gets the HTTP response associated with this event. - /// - /// The HTTP response associated with this event. - public HttpWebResponse Response { get; internal set; } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RequestResult.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RequestResult.cs deleted file mode 100644 index 47becdd85282e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RequestResult.cs +++ /dev/null @@ -1,286 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Text; - using System.Xml; - - /// - /// Represents the result of a physical request. - /// -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - [Serializable] -#endif - public sealed class RequestResult - { - private int httpStatusCode = -1; - - private volatile Exception exception = null; - - /// - /// Gets or sets the HTTP status code for the request. - /// - /// The HTTP status code for the request. - public int HttpStatusCode - { - get - { - return this.httpStatusCode; - } - - set - { - this.httpStatusCode = value; - } - } - - /// - /// Gets the HTTP status message for the request. - /// - /// The HTTP status message for the request. - public string HttpStatusMessage { get; internal set; } - - /// - /// Gets the service request ID for this request. - /// - /// The service request ID for this request. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Justification = "Back compatibility.")] - public string ServiceRequestID { get; internal set; } - - /// - /// Gets the content-MD5 value for the request. - /// - /// The content-MD5 value for the request. - [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Md", Justification = "Back compatibility.")] - public string ContentMd5 { get; internal set; } - - /// - /// Gets the ETag value of the request. - /// - /// The ETag value of the request. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Etag", Justification = "Reviewed: Etag can be used for identifier names.")] - public string Etag { get; internal set; } - - /// - /// Gets the request date. - /// - /// The request date. - public string RequestDate { get; internal set; } - - /// - /// Gets the extended error information. - /// - /// The extended error information. - public StorageExtendedErrorInformation ExtendedErrorInformation { get; internal set; } - - /// - /// Gets or sets the exception. - /// - /// The exception. - public Exception Exception - { - get - { - return this.exception; - } - - set - { -#if WINDOWS_RT - this.ExceptionInfo = (value != null) ? new ExceptionInfo(value) : null; -#endif - this.exception = value; - } - } - -#if WINDOWS_RT - public DateTimeOffset StartTime { get; internal set; } - - public DateTimeOffset EndTime { get; internal set; } - - public ExceptionInfo ExceptionInfo { get; internal set; } -#else - /// - /// Gets the start time of the operation. - /// - /// The start time of the operation. - public DateTime StartTime { get; internal set; } - - /// - /// Gets the end time of the operation. - /// - /// The end time of the operation. - public DateTime EndTime { get; internal set; } -#endif - /// - /// Translates the specified message into a object. - /// - /// The message to translate. - /// The translated . -#if WINDOWS_DESKTOP - [Obsolete("This should be available only in Microsoft.WindowsAzure.Storage.WinMD and not in Microsoft.WindowsAzure.Storage.dll. Please use ReadXML to deserialize RequestResult when Microsoft.WindowsAzure.Storage.dll is used.")] -#endif - public static RequestResult TranslateFromExceptionMessage(string message) - { - RequestResult res = new RequestResult(); - - using (XmlReader reader = XmlReader.Create(new StringReader(message))) - { - res.ReadXml(reader); - } - - return res; - } - - internal string WriteAsXml() - { - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - try - { - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - this.WriteXml(writer); - } - - return sb.ToString(); - } - catch (XmlException) - { - return null; - } - } - - #region XML Serializable - - /// - /// Generates a serializable RequestResult from its XML representation. - /// - /// The stream from which the RequestResult is deserialized. -#if WINDOWS_RT - internal -#else - public -#endif - void ReadXml(XmlReader reader) - { - CommonUtility.AssertNotNull("reader", reader); - - reader.Read(); - - if (reader.NodeType == XmlNodeType.Comment) - { - reader.Read(); - } - - reader.ReadStartElement("RequestResult"); - - this.httpStatusCode = int.Parse(CommonUtility.ReadElementAsString("HTTPStatusCode", reader), CultureInfo.InvariantCulture); - this.HttpStatusMessage = CommonUtility.ReadElementAsString("HttpStatusMessage", reader); - this.ServiceRequestID = CommonUtility.ReadElementAsString("ServiceRequestID", reader); - - this.ContentMd5 = CommonUtility.ReadElementAsString("ContentMd5", reader); - this.Etag = CommonUtility.ReadElementAsString("Etag", reader); - this.RequestDate = CommonUtility.ReadElementAsString("RequestDate", reader); -#if WINDOWS_RT - this.StartTime = DateTimeOffset.Parse(CommonUtility.ReadElementAsString("StartTime", reader)); - this.EndTime = DateTimeOffset.Parse(CommonUtility.ReadElementAsString("EndTime", reader)); -#else - this.StartTime = DateTime.Parse(CommonUtility.ReadElementAsString("StartTime", reader), CultureInfo.InvariantCulture); - this.EndTime = DateTime.Parse(CommonUtility.ReadElementAsString("EndTime", reader), CultureInfo.InvariantCulture); -#endif - this.ExtendedErrorInformation = new StorageExtendedErrorInformation(); - this.ExtendedErrorInformation.ReadXml(reader); - -#if WINDOWS_RT - this.ExceptionInfo = ExceptionInfo.ReadFromXMLReader(reader); -#endif - // End request Result - reader.ReadEndElement(); - } - - /// - /// Converts a serializable RequestResult into its XML representation. - /// - /// The stream to which the RequestResult is serialized. - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "TranslateFromExceptionMessage", Justification = "TranslateFromException is a field name that when split could confuse the users")] - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "RequestResult", Justification = "RequestResult is a variable name which when split could confuse the users")] - [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Xml.XmlWriter.WriteComment(System.String)", Justification = "Reviewed. Literals can be used in an internal method")] -#if WINDOWS_RT - internal -#else - public -#endif - void WriteXml(XmlWriter writer) - { - CommonUtility.AssertNotNull("writer", writer); - - writer.WriteComment(SR.ExceptionOccurred); - writer.WriteStartElement("RequestResult"); - writer.WriteElementString("HTTPStatusCode", Convert.ToString(this.HttpStatusCode, CultureInfo.InvariantCulture)); - writer.WriteElementString("HttpStatusMessage", this.HttpStatusMessage); - - // Headers - writer.WriteElementString("ServiceRequestID", this.ServiceRequestID); - writer.WriteElementString("ContentMd5", this.ContentMd5); - writer.WriteElementString("Etag", this.Etag); - writer.WriteElementString("RequestDate", this.RequestDate); - - // Dates - using RFC 1123 pattern - writer.WriteElementString("StartTime", this.StartTime.ToUniversalTime().ToString("R", CultureInfo.InvariantCulture)); - writer.WriteElementString("EndTime", this.EndTime.ToUniversalTime().ToString("R", CultureInfo.InvariantCulture)); - - // Extended info - if (this.ExtendedErrorInformation != null) - { - this.ExtendedErrorInformation.WriteXml(writer); - } - else - { - // Write empty - writer.WriteStartElement(Constants.ErrorRootElement); - writer.WriteFullEndElement(); - } -#if WINDOWS_RT - // Exception - if (this.ExceptionInfo != null) - { - this.ExceptionInfo.WriteXml(writer); - } - else - { - // Write empty - writer.WriteStartElement("ExceptionInfo"); - writer.WriteFullEndElement(); - } -#endif - - // End RequestResult - writer.WriteEndElement(); - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/ResultSegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/ResultSegment.cs deleted file mode 100644 index b5700cbba71f0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/ResultSegment.cs +++ /dev/null @@ -1,81 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a result segment that was retrieved from the total set of possible results. - /// - /// The type of the element. - [SuppressMessage( - "Microsoft.StyleCop.CSharp.MaintainabilityRules", - "SA1402:FileMayOnlyContainASingleClass", - Justification = "Other class is a non-generic static helper with the same name.")] -#if WINDOWS_RT - internal -#else - public -#endif - class ResultSegment - { - /// - /// Stores the continuation token used to retrieve the next segment of results. - /// - private IContinuationToken continuationToken; - - /// - /// Initializes a new instance of the ResultSegment class. - /// - /// The result. - internal ResultSegment(List result) - { - this.Results = result; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - [SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Justification = "Reviewed.")] - public List Results { get; internal set; } - - /// - /// Gets a continuation token to use to retrieve the next set of results with a subsequent call to the operation. - /// - /// The continuation token. - public IContinuationToken ContinuationToken - { - get - { - if (this.continuationToken != null) - { - return this.continuationToken; - } - - return null; - } - - internal set - { - this.continuationToken = value; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/ExponentialRetry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/ExponentialRetry.cs deleted file mode 100644 index 103072420157e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/ExponentialRetry.cs +++ /dev/null @@ -1,106 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.RetryPolicies -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a retry policy that performs a specified number of retries, using a randomized exponential back off scheme to determine the interval between retries. - /// - public sealed class ExponentialRetry : IRetryPolicy - { - private const int DefaultClientRetryCount = 3; - private static readonly TimeSpan DefaultClientBackoff = TimeSpan.FromSeconds(4); - private TimeSpan maxBackoff = TimeSpan.FromSeconds(120); - private TimeSpan minBackoff = TimeSpan.FromSeconds(3); - - private TimeSpan deltaBackoff; - private int maximumAttempts; - - /// - /// Initializes a new instance of the class. - /// - public ExponentialRetry() - : this(DefaultClientBackoff, DefaultClientRetryCount) - { - } - - /// - /// Initializes a new instance of the class using the specified delta and maximum number of retries. - /// - /// The back off interval between retries. - /// The maximum number of retry attempts. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Backoff", Justification = "Reviewed: Backoff is allowed.")] - public ExponentialRetry(TimeSpan deltaBackoff, int maxAttempts) - { - this.deltaBackoff = deltaBackoff; - this.maximumAttempts = maxAttempts; - } - - /// - /// Determines if the operation should be retried and how long to wait until the next retry. - /// - /// The number of retries for the given operation. A value of zero signifies this is the first error encountered. - /// The status code for the last operation. - /// An object that represents the last exception encountered. - /// The interval to wait until the next retry. - /// An object for tracking the current operation. - /// true if the operation should be retried; otherwise, false. - public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext) - { - CommonUtility.AssertNotNull("lastException", lastException); - - retryInterval = TimeSpan.Zero; - - // If this method is called after a successful response, it means - // we failed during the response body download. So, we should not - // check for success codes here. - if ((statusCode >= 300 && statusCode < 500 && statusCode != 408) - || statusCode == 501 // Not Implemented - || statusCode == 505 // Version Not Supported - || lastException.Message == SR.BlobTypeMismatch) - { - return false; - } - - if (currentRetryCount < this.maximumAttempts) - { - Random r = new Random(); - double increment = (Math.Pow(2, currentRetryCount) - 1) * r.Next((int)(this.deltaBackoff.TotalMilliseconds * 0.8), (int)(this.deltaBackoff.TotalMilliseconds * 1.2)); - retryInterval = (increment < 0) ? - this.maxBackoff : - TimeSpan.FromMilliseconds(Math.Min(this.maxBackoff.TotalMilliseconds, this.minBackoff.TotalMilliseconds + increment)); - return true; - } - - return false; - } - - /// - /// Generates a new retry policy for the current request attempt. - /// - /// An object that represents the retry policy for the current request attempt. - public IRetryPolicy CreateInstance() - { - return new ExponentialRetry(this.deltaBackoff, this.maximumAttempts); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/IRetryPolicy.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/IRetryPolicy.cs deleted file mode 100644 index dd9b0700971e0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/IRetryPolicy.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.RetryPolicies -{ - using System; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a retry policy. - /// - public interface IRetryPolicy - { - /// - /// Generates a new retry policy for the current request attempt. - /// - /// An object that represents the retry policy for the current request attempt. - IRetryPolicy CreateInstance(); - - /// - /// Determines if the operation should be retried and how long to wait until the next retry. - /// - /// The number of retries for the given operation. A value of zero signifies this is the first error encountered. - /// The status code for the last operation. - /// An object that represents the last exception encountered. - /// The interval to wait until the next retry. - /// An object for tracking the current operation. - /// true if the operation should be retried; otherwise, false. - [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "3#", Justification = "Back compatibility")] - bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/LinearRetry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/LinearRetry.cs deleted file mode 100644 index 7042bd8a0964a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/LinearRetry.cs +++ /dev/null @@ -1,95 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.RetryPolicies -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a retry policy that performs a specified number of retries, using a specified fixed time interval between retries. - /// - public sealed class LinearRetry : IRetryPolicy - { - private const int DefaultClientRetryCount = 3; - - private static readonly TimeSpan DefaultClientBackoff = TimeSpan.FromSeconds(30); - private TimeSpan deltaBackoff; - private int maximumAttempts; - - /// - /// Initializes a new instance of the class. - /// - public LinearRetry() - : this(DefaultClientBackoff, DefaultClientRetryCount) - { - } - - /// - /// Initializes a new instance of the class using the specified delta and maximum number of retries. - /// - /// The back off interval between retries. - /// The maximum number of retry attempts. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Backoff", Justification = "Reviewed: Backoff is allowed.")] - public LinearRetry(TimeSpan deltaBackoff, int maxAttempts) - { - this.deltaBackoff = deltaBackoff; - this.maximumAttempts = maxAttempts; - } - - /// - /// Determines if the operation should be retried and how long to wait until the next retry. - /// - /// The number of retries for the given operation. A value of zero signifies this is the first error encountered. - /// The status code for the last operation. - /// An object that represents the last exception encountered. - /// The interval to wait until the next retry. - /// An object for tracking the current operation. - /// true if the operation should be retried; otherwise, false. - public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext) - { - CommonUtility.AssertNotNull("lastException", lastException); - - retryInterval = TimeSpan.Zero; - - // If this method is called after a successful response, it means - // we failed during the response body download. So, we should not - // check for success codes here. - if ((statusCode >= 300 && statusCode < 500 && statusCode != 408) - || statusCode == 501 // Not Implemented - || statusCode == 505 // Version Not Supported - || lastException.Message == SR.BlobTypeMismatch) - { - return false; - } - - retryInterval = this.deltaBackoff; - return currentRetryCount < this.maximumAttempts; - } - - /// - /// Generates a new retry policy for the current request attempt. - /// - /// An object that represents the retry policy for the current request attempt. - public IRetryPolicy CreateInstance() - { - return new LinearRetry(this.deltaBackoff, this.maximumAttempts); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/NoRetry.cs b/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/NoRetry.cs deleted file mode 100644 index 7c23c699d68a8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/RetryPolicies/NoRetry.cs +++ /dev/null @@ -1,58 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.RetryPolicies -{ - using System; - - /// - /// Represents a retry policy that performs no retries. - /// - public sealed class NoRetry : IRetryPolicy - { - /// - /// Initializes a new instance of the class. - /// - public NoRetry() - { - } - - /// - /// Determines if the operation should be retried and how long to wait until the next retry. - /// - /// The number of retries for the given operation. A value of zero signifies this is the first error encountered. - /// The status code for the last operation. - /// An object that represents the last exception encountered. - /// The interval to wait until the next retry. - /// An object for tracking the current operation. - /// true if the operation should be retried; otherwise, false. - public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext) - { - retryInterval = TimeSpan.Zero; - return false; - } - - /// - /// Generates a new retry policy for the current request attempt. - /// - /// An object that represents the retry policy for the current request attempt. - public IRetryPolicy CreateInstance() - { - return new NoRetry(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/AccessPolicyResponseBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/AccessPolicyResponseBase.cs deleted file mode 100644 index 9317434f446ae..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/AccessPolicyResponseBase.cs +++ /dev/null @@ -1,84 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.Collections.Generic; - using System.IO; - using System.Xml.Linq; - - /// - /// Parses the response XML from an operation to set the access policy for a cloud object. - /// - /// The policy type to be filled. - internal abstract class AccessPolicyResponseBase : ResponseParsingBase> - where T : new() - { - /// - /// Initializes a new instance of the AccessPolicyResponseBase class. - /// - /// The stream to be parsed. - protected AccessPolicyResponseBase(Stream stream) : base(stream) - { - } - - /// - /// Gets an enumerable collection of container-level access policy identifiers. - /// - /// An enumerable collection of container-level access policy identifiers. - public IEnumerable> AccessIdentifiers - { - get - { - return this.ObjectsToParse; - } - } - - /// - /// Parses the current element. - /// - /// The shared access policy element to parse. - /// The shared access policy. - protected abstract T ParseElement(XElement accessPolicyElement); - - /// - /// Parses the response XML from a Set Container ACL operation to retrieve container-level access policy data. - /// - /// A list of enumerable key-value pairs. - protected override IEnumerable> ParseXml() - { - XElement root = XElement.Load(reader); - IEnumerable elements = root.Elements(Constants.SignedIdentifier); - foreach (XElement signedIdentifierElement in elements) - { - string id = (string)signedIdentifierElement.Element(Constants.Id); - T accessPolicy; - XElement accessPolicyElement = signedIdentifierElement.Element(Constants.AccessPolicy); - if (accessPolicyElement != null) - { - accessPolicy = this.ParseElement(accessPolicyElement); - } - else - { - accessPolicy = new T(); - } - - yield return new KeyValuePair(id, accessPolicy); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Constants.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Constants.cs deleted file mode 100644 index 25f1fd3b86169..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Constants.cs +++ /dev/null @@ -1,1096 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Contains storage constants. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class Constants - { - /// - /// Maximum number of shared access policy identifiers supported by server. - /// - public const int MaxSharedAccessPolicyIdentifiers = 5; - - /// - /// Default Write Block Size used by Blob stream. - /// - public const int DefaultWriteBlockSizeBytes = (int)(4 * Constants.MB); - - /// - /// The maximum size of a blob before it must be separated into blocks. - /// - public const long MaxSingleUploadBlobSize = 64 * MB; - - /// - /// The maximum size of a single block. - /// - public const int MaxBlockSize = (int)(4 * Constants.MB); - - /// - /// The maximum size of a range get operation that returns content MD5. - /// - public const int MaxRangeGetContentMD5Size = (int)(4 * Constants.MB); - - /// - /// The maximum number of blocks. - /// - public const long MaxBlockNumber = 50000; - - /// - /// The maximum size of a blob with blocks. - /// - public const long MaxBlobSize = MaxBlockNumber * MaxBlockSize; - - /// - /// Default client side timeout for all service clients. - /// - public static readonly TimeSpan DefaultClientSideTimeout = TimeSpan.FromMinutes(5); - - /// - /// Default server side timeout for all service clients. - /// - public static readonly TimeSpan DefaultServerSideTimeout = TimeSpan.FromSeconds(90); - - /// - /// Maximum Retry Policy back-off - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Backoff", Justification = "Reviewed")] - public static readonly TimeSpan MaximumRetryBackoff = TimeSpan.FromHours(1); - - /// - /// Maximum allowed timeout for any request. - /// - public static readonly TimeSpan MaximumAllowedTimeout = TimeSpan.FromSeconds(int.MaxValue); - - /// - /// Default size of buffer for unknown sized requests. - /// - internal const int DefaultBufferSize = (int)(64 * KB); - - /// - /// Common name to be used for all loggers. - /// - internal const string LogSourceName = "Microsoft.WindowsAzure.Storage"; - - /// - /// The size of a page in a PageBlob. - /// - internal const int PageSize = 512; - - /// - /// A constant representing a kilo-byte (Non-SI version). - /// - internal const long KB = 1024; - - /// - /// A constant representing a megabyte (Non-SI version). - /// - internal const long MB = 1024 * KB; - - /// - /// A constant representing a megabyte (Non-SI version). - /// - internal const long GB = 1024 * MB; - - /// - /// XML element for committed blocks. - /// - public const string CommittedBlocksElement = "CommittedBlocks"; - - /// - /// XML element for uncommitted blocks. - /// - public const string UncommittedBlocksElement = "UncommittedBlocks"; - - /// - /// XML element for blocks. - /// - public const string BlockElement = "Block"; - - /// - /// XML element for names. - /// - public const string NameElement = "Name"; - - /// - /// XML element for sizes. - /// - public const string SizeElement = "Size"; - - /// - /// XML element for block lists. - /// - public const string BlockListElement = "BlockList"; - - /// - /// XML element for queue message lists. - /// - public const string MessagesElement = "QueueMessagesList"; - - /// - /// XML element for queue messages. - /// - public const string MessageElement = "QueueMessage"; - - /// - /// XML element for message IDs. - /// - public const string MessageIdElement = "MessageId"; - - /// - /// XML element for insertion times. - /// - public const string InsertionTimeElement = "InsertionTime"; - - /// - /// XML element for expiration times. - /// - public const string ExpirationTimeElement = "ExpirationTime"; - - /// - /// XML element for pop receipts. - /// - public const string PopReceiptElement = "PopReceipt"; - - /// - /// XML element for the time next visible fields. - /// - public const string TimeNextVisibleElement = "TimeNextVisible"; - - /// - /// XML element for message texts. - /// - public const string MessageTextElement = "MessageText"; - - /// - /// XML element for dequeue counts. - /// - public const string DequeueCountElement = "DequeueCount"; - - /// - /// XML element for page ranges. - /// - public const string PageRangeElement = "PageRange"; - - /// - /// XML element for page list elements. - /// - public const string PageListElement = "PageList"; - - /// - /// XML element for page range start elements. - /// - public const string StartElement = "Start"; - - /// - /// XML element for page range end elements. - /// - public const string EndElement = "End"; - - /// - /// XML element for delimiters. - /// - public const string DelimiterElement = "Delimiter"; - - /// - /// XML element for blob prefixes. - /// - public const string BlobPrefixElement = "BlobPrefix"; - - /// - /// XML element for content type fields. - /// - public const string CacheControlElement = "Cache-Control"; - - /// - /// XML element for content type fields. - /// - public const string ContentTypeElement = "Content-Type"; - - /// - /// XML element for content encoding fields. - /// - public const string ContentEncodingElement = "Content-Encoding"; - - /// - /// XML element for content language fields. - /// - public const string ContentLanguageElement = "Content-Language"; - - /// - /// XML element for content length fields. - /// - public const string ContentLengthElement = "Content-Length"; - - /// - /// XML element for content MD5 fields. - /// - public const string ContentMD5Element = "Content-MD5"; - - /// - /// XML element for enumeration results. - /// - public const string EnumerationResultsElement = "EnumerationResults"; - - /// - /// XML element for blobs. - /// - public const string BlobsElement = "Blobs"; - - /// - /// XML element for prefixes. - /// - public const string PrefixElement = "Prefix"; - - /// - /// XML element for maximum results. - /// - public const string MaxResultsElement = "MaxResults"; - - /// - /// XML element for markers. - /// - public const string MarkerElement = "Marker"; - - /// - /// XML element for the next marker. - /// - public const string NextMarkerElement = "NextMarker"; - - /// - /// XML element for the ETag. - /// - public const string EtagElement = "Etag"; - - /// - /// XML element for the last modified date. - /// - public const string LastModifiedElement = "Last-Modified"; - - /// - /// XML element for the Url. - /// - public const string UrlElement = "Url"; - - /// - /// XML element for blobs. - /// - public const string BlobElement = "Blob"; - - /// - /// XML element for copy ID. - /// - public const string CopyIdElement = "CopyId"; - - /// - /// XML element for copy status. - /// - public const string CopyStatusElement = "CopyStatus"; - - /// - /// XML element for copy source. - /// - public const string CopySourceElement = "CopySource"; - - /// - /// XML element for copy progress. - /// - public const string CopyProgressElement = "CopyProgress"; - - /// - /// XML element for copy completion time. - /// - public const string CopyCompletionTimeElement = "CopyCompletionTime"; - - /// - /// XML element for copy status description. - /// - public const string CopyStatusDescriptionElement = "CopyStatusDescription"; - - /// - /// Constant signaling a page blob. - /// - public const string PageBlobValue = "PageBlob"; - - /// - /// Constant signaling a block blob. - /// - public const string BlockBlobValue = "BlockBlob"; - - /// - /// Constant signaling the blob is locked. - /// - public const string LockedValue = "locked"; - - /// - /// Constant signaling the blob is unlocked. - /// - public const string UnlockedValue = "unlocked"; - - /// - /// Constant signaling the resource is available for leasing. - /// - public const string LeaseAvailableValue = "available"; - - /// - /// Constant signaling the resource is leased. - /// - public const string LeasedValue = "leased"; - - /// - /// Constant signaling the resource's lease has expired. - /// - public const string LeaseExpiredValue = "expired"; - - /// - /// Constant signaling the resource's lease is breaking. - /// - public const string LeaseBreakingValue = "breaking"; - - /// - /// Constant signaling the resource's lease is broken. - /// - public const string LeaseBrokenValue = "broken"; - - /// - /// Constant signaling the resource's lease is infinite. - /// - public const string LeaseInfiniteValue = "infinite"; - - /// - /// Constant signaling the resource's lease is fixed (finite). - /// - public const string LeaseFixedValue = "fixed"; - - /// - /// Constant for a pending copy. - /// - public const string CopyPendingValue = "pending"; - - /// - /// Constant for a successful copy. - /// - public const string CopySuccessValue = "success"; - - /// - /// Constant for an aborted copy. - /// - public const string CopyAbortedValue = "aborted"; - - /// - /// Constant for a failed copy. - /// - public const string CopyFailedValue = "failed"; - - /// - /// XML element for blob types. - /// - public const string BlobTypeElement = "BlobType"; - - /// - /// XML element for the lease status. - /// - public const string LeaseStatusElement = "LeaseStatus"; - - /// - /// XML element for the lease status. - /// - public const string LeaseStateElement = "LeaseState"; - - /// - /// XML element for the lease status. - /// - public const string LeaseDurationElement = "LeaseDuration"; - - /// - /// XML element for snapshots. - /// - public const string SnapshotElement = "Snapshot"; - - /// - /// XML element for containers. - /// - public const string ContainersElement = "Containers"; - - /// - /// XML element for a container. - /// - public const string ContainerElement = "Container"; - - /// - /// XML element for queues. - /// - public const string QueuesElement = "Queues"; - - /// - /// Version 2 of the XML element for the queue name. - /// - public const string QueueNameElement = "Name"; - - /// - /// XML element for the queue. - /// - public const string QueueElement = "Queue"; - - /// - /// XML element for properties. - /// - public const string PropertiesElement = "Properties"; - - /// - /// XML element for the metadata. - /// - public const string MetadataElement = "Metadata"; - - /// - /// XML element for an invalid metadata name. - /// - public const string InvalidMetadataName = "x-ms-invalid-name"; - - /// - /// XML element for maximum results. - /// - public const string MaxResults = "MaxResults"; - - /// - /// XML element for committed blocks. - /// - public const string CommittedElement = "Committed"; - - /// - /// XML element for uncommitted blocks. - /// - public const string UncommittedElement = "Uncommitted"; - - /// - /// XML element for the latest. - /// - public const string LatestElement = "Latest"; - - /// - /// XML element for signed identifiers. - /// - public const string SignedIdentifiers = "SignedIdentifiers"; - - /// - /// XML element for a signed identifier. - /// - public const string SignedIdentifier = "SignedIdentifier"; - - /// - /// XML element for access policies. - /// - public const string AccessPolicy = "AccessPolicy"; - - /// - /// XML attribute for IDs. - /// - public const string Id = "Id"; - - /// - /// XML element for the start time of an access policy. - /// - public const string Start = "Start"; - - /// - /// XML element for the end of an access policy. - /// - public const string Expiry = "Expiry"; - - /// - /// XML element for the permissions of an access policy. - /// - public const string Permission = "Permission"; - - /// - /// The URI path component to access the messages in a queue. - /// - public const string Messages = "messages"; - - /// - /// XML element for exception details. - /// - internal const string ErrorException = "exceptiondetails"; - - /// - /// XML root element for errors. - /// - public const string ErrorRootElement = "Error"; - - /// - /// XML element for error codes. - /// - public const string ErrorCode = "Code"; - - /// - /// XML element for error codes returned by the preview tenants. - /// - internal const string ErrorCodePreview = "code"; - - /// - /// XML element for error messages. - /// - public const string ErrorMessage = "Message"; - - /// - /// XML element for error messages. - /// - internal const string ErrorMessagePreview = "message"; - - /// - /// XML element for exception messages. - /// - public const string ErrorExceptionMessage = "ExceptionMessage"; - - /// - /// XML element for stack traces. - /// - public const string ErrorExceptionStackTrace = "StackTrace"; - - /// - /// Constants for HTTP headers. - /// - [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Reviewed.")] - public static class HeaderConstants - { - static HeaderConstants() - { -#if WINDOWS_PHONE - UserAgentComment = string.Format(CultureInfo.InvariantCulture, "(.NET CLR {0}; Windows Phone {1})", Environment.Version, Environment.OSVersion.Version); -#elif WINDOWS_RT - UserAgentComment = "(Windows Runtime)"; -#else - UserAgentComment = string.Format(CultureInfo.InvariantCulture, "(.NET CLR {0}; {1} {2})", Environment.Version, Environment.OSVersion.Platform, Environment.OSVersion.Version); -#endif - - UserAgent = UserAgentProductName + "/" + UserAgentProductVersion + " " + UserAgentComment; - } - - /// - /// Specifies the value to use for UserAgent header. - /// - public static readonly string UserAgent; - - /// - /// Specifies the comment to use for UserAgent header. - /// - public static readonly string UserAgentComment; - - /// - /// Specifies the value to use for UserAgent header. - /// - public const string UserAgentProductName = "WA-Storage"; - - /// - /// Specifies the value to use for UserAgent header. - /// - public const string UserAgentProductVersion = "2.1.0.4"; - - /// - /// Master Windows Azure Storage header prefix. - /// - internal const string PrefixForStorageHeader = "x-ms-"; - - /// - /// True Header. - /// - public const string TrueHeader = "true"; - - /// - /// False Header. - /// - public const string FalseHeader = "false"; - - /// - /// Header prefix for properties. - /// - internal const string PrefixForStorageProperties = "x-ms-prop-"; - - /// - /// Header prefix for metadata. - /// - internal const string PrefixForStorageMetadata = "x-ms-meta-"; - - /// - /// Header that specifies content length. - /// - public const string ContentLengthHeader = "content-length"; - - /// - /// Header that specifies content language. - /// - public const string ContentLanguageHeader = "content-language"; - - /// - /// Header for data ranges. - /// - public const string RangeHeader = PrefixForStorageHeader + "range"; - - /// - /// Header for range content MD5. - /// - public const string RangeContentMD5Header = PrefixForStorageHeader + "range-get-content-md5"; - - /// - /// Header for storage version. - /// - public const string StorageVersionHeader = PrefixForStorageHeader + "version"; - - /// - /// Header for copy source. - /// - public const string CopySourceHeader = PrefixForStorageHeader + "copy-source"; - - /// - /// Header for the If-Match condition. - /// - public const string SourceIfMatchHeader = PrefixForStorageHeader + "source-if-match"; - - /// - /// Header for the If-Modified-Since condition. - /// - public const string SourceIfModifiedSinceHeader = PrefixForStorageHeader + "source-if-modified-since"; - - /// - /// Header for the If-None-Match condition. - /// - public const string SourceIfNoneMatchHeader = PrefixForStorageHeader + "source-if-none-match"; - - /// - /// Header for the If-Unmodified-Since condition. - /// - public const string SourceIfUnmodifiedSinceHeader = PrefixForStorageHeader + "source-if-unmodified-since"; - - /// - /// Header for the If-Sequence-Number-LE condition. - /// - public const string IfSequenceNumberLEHeader = PrefixForStorageHeader + "if-sequence-number-le"; - - /// - /// Header for the If-Sequence-Number-LT condition. - /// - public const string IfSequenceNumberLTHeader = PrefixForStorageHeader + "if-sequence-number-lt"; - - /// - /// Header for the If-Sequence-Number-EQ condition. - /// - public const string IfSequenceNumberEqHeader = PrefixForStorageHeader + "if-sequence-number-eq"; - - /// - /// Header for the blob type. - /// - public const string BlobType = PrefixForStorageHeader + "blob-type"; - - /// - /// Header for snapshots. - /// - public const string SnapshotHeader = PrefixForStorageHeader + "snapshot"; - - /// - /// Header to delete snapshots. - /// - public const string DeleteSnapshotHeader = PrefixForStorageHeader + "delete-snapshots"; - - /// - /// Header that specifies approximate message count of a queue. - /// - public const string ApproximateMessagesCount = PrefixForStorageHeader + "approximate-messages-count"; - - /// - /// Header that specifies blob caching control. - /// - public const string CacheControlHeader = PrefixForStorageHeader + "blob-cache-control"; - - /// - /// Header that specifies blob content encoding. - /// - public const string ContentEncodingHeader = PrefixForStorageHeader + "blob-content-encoding"; - - /// - /// Header that specifies blob content language. - /// - public const string BlobContentLanguageHeader = PrefixForStorageHeader + "blob-content-language"; - - /// - /// Header that specifies blob content MD5. - /// - public const string BlobContentMD5Header = PrefixForStorageHeader + "blob-content-md5"; - - /// - /// Header that specifies blob content type. - /// - public const string ContentTypeHeader = PrefixForStorageHeader + "blob-content-type"; - - /// - /// Header that specifies blob content length. - /// - public const string BlobContentLengthHeader = PrefixForStorageHeader + "blob-content-length"; - - /// - /// Header that specifies blob sequence number. - /// - public const string BlobSequenceNumber = PrefixForStorageHeader + "blob-sequence-number"; - - /// - /// Header that specifies sequence number action. - /// - public const string SequenceNumberAction = PrefixForStorageHeader + "sequence-number-action"; - - /// - /// Header that specifies lease ID. - /// - public const string LeaseIdHeader = PrefixForStorageHeader + "lease-id"; - - /// - /// Header that specifies lease status. - /// - public const string LeaseStatus = PrefixForStorageHeader + "lease-status"; - - /// - /// Header that specifies lease status. - /// - public const string LeaseState = PrefixForStorageHeader + "lease-state"; - - /// - /// Header that specifies page write mode. - /// - public const string PageWrite = PrefixForStorageHeader + "page-write"; - - /// - /// Header that specifies the date. - /// - public const string Date = PrefixForStorageHeader + "date"; - - /// - /// Header indicating the request ID. - /// - public const string RequestIdHeader = PrefixForStorageHeader + "request-id"; - - /// - /// Header indicating the client request ID. - /// - public const string ClientRequestIdHeader = PrefixForStorageHeader + "client-request-id"; - - /// - /// Header that specifies public access to blobs. - /// - public const string BlobPublicAccess = PrefixForStorageHeader + "blob-public-access"; - - /// - /// Format string for specifying ranges. - /// - public const string RangeHeaderFormat = "bytes={0}-{1}"; - - /// - /// Current storage version header value. - /// Every time this version changes, assembly version needs to be updated as well. - /// - internal const string TargetStorageVersion = "2012-02-12"; - - /// - /// Specifies the page blob type. - /// - public const string PageBlob = "PageBlob"; - - /// - /// Specifies the block blob type. - /// - public const string BlockBlob = "BlockBlob"; - - /// - /// Specifies only snapshots are to be included. - /// - public const string SnapshotsOnlyValue = "only"; - - /// - /// Specifies snapshots are to be included. - /// - public const string IncludeSnapshotsValue = "include"; - - /// - /// Header that specifies the pop receipt for a message. - /// - public const string PopReceipt = PrefixForStorageHeader + "popreceipt"; - - /// - /// Header that specifies the next visible time for a message. - /// - public const string NextVisibleTime = PrefixForStorageHeader + "time-next-visible"; - - /// - /// Header that specifies whether to peek-only. - /// - public const string PeekOnly = "peekonly"; - - /// - /// Header that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// - public const string ContainerPublicAccessType = PrefixForStorageHeader + "blob-public-access"; - - /// - /// Header that specifies the lease action to perform. - /// - public const string LeaseActionHeader = PrefixForStorageHeader + "lease-action"; - - /// - /// Header that specifies the proposed lease ID for a leasing operation. - /// - public const string ProposedLeaseIdHeader = PrefixForStorageHeader + "proposed-lease-id"; - - /// - /// Header that specifies the duration of a lease. - /// - public const string LeaseDurationHeader = PrefixForStorageHeader + "lease-duration"; - - /// - /// Header that specifies the break period of a lease. - /// - public const string LeaseBreakPeriodHeader = PrefixForStorageHeader + "lease-break-period"; - - /// - /// Header that specifies the remaining lease time. - /// - public const string LeaseTimeHeader = PrefixForStorageHeader + "lease-time"; - - /// - /// Header that specifies the key name for explicit keys. - /// - public const string KeyNameHeader = PrefixForStorageHeader + "key-name"; - - /// - /// Header that specifies the copy ID. - /// - public const string CopyIdHeader = PrefixForStorageHeader + "copy-id"; - - /// - /// Header that specifies the copy last modified time. - /// - public const string CopyCompletionTimeHeader = PrefixForStorageHeader + "copy-completion-time"; - - /// - /// Header that specifies the copy status. - /// - public const string CopyStatusHeader = PrefixForStorageHeader + "copy-status"; - - /// - /// Header that specifies the copy progress. - /// - public const string CopyProgressHeader = PrefixForStorageHeader + "copy-progress"; - - /// - /// Header that specifies a copy error message. - /// - public const string CopyDescriptionHeader = PrefixForStorageHeader + "copy-status-description"; - - /// - /// Header that specifies the copy action. - /// - public const string CopyActionHeader = PrefixForStorageHeader + "copy-action"; - - /// - /// The value of the copy action header that signifies an abort operation. - /// - public const string CopyActionAbort = "abort"; - } - - /// - /// Constants for query strings. - /// - [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Reviewed.")] - public static class QueryConstants - { - /// - /// Query component for snapshot time. - /// - public const string Snapshot = "snapshot"; - - /// - /// Query component for the signed SAS start time. - /// - public const string SignedStart = "st"; - - /// - /// Query component for the signed SAS expiry time. - /// - public const string SignedExpiry = "se"; - - /// - /// Query component for the signed SAS resource. - /// - public const string SignedResource = "sr"; - - /// - /// Query component for the SAS table name. - /// - public const string SasTableName = "tn"; - - /// - /// Query component for the signed SAS permissions. - /// - public const string SignedPermissions = "sp"; - - /// - /// Query component for the SAS start partition key. - /// - public const string StartPartitionKey = "spk"; - - /// - /// Query component for the SAS start row key. - /// - public const string StartRowKey = "srk"; - - /// - /// Query component for the SAS end partition key. - /// - public const string EndPartitionKey = "epk"; - - /// - /// Query component for the SAS end row key. - /// - public const string EndRowKey = "erk"; - - /// - /// Query component for the signed SAS identifier. - /// - public const string SignedIdentifier = "si"; - - /// - /// Query component for the signing SAS key. - /// - public const string SignedKey = "sk"; - - /// - /// Query component for the signed SAS version. - /// - public const string SignedVersion = "sv"; - - /// - /// Query component for SAS signature. - /// - public const string Signature = "sig"; - - /// - /// Query component for message time-to-live. - /// - public const string MessageTimeToLive = "messagettl"; - - /// - /// Query component for message visibility timeout. - /// - public const string VisibilityTimeout = "visibilitytimeout"; - - /// - /// Query component for the number of messages. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Num", Justification = "Reviewed : Num is allowed in an identifier name.")] - public const string NumOfMessages = "numofmessages"; - - /// - /// Query component for message pop receipt. - /// - public const string PopReceipt = "popreceipt"; - - /// - /// Query component for resource type. - /// - public const string ResourceType = "restype"; - - /// - /// Query component for the operation (component) to access. - /// - public const string Component = "comp"; - - /// - /// Query component for the copy ID. - /// - public const string CopyId = "copyid"; - } - - /// - /// Constants for Result Continuations - /// - [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Reviewed.")] - public static class ContinuationConstants - { - /// - /// Top Element for Continuation Tokens - /// - public const string ContinuationTopElement = "ContinuationToken"; - - /// - /// XML element for the next marker. - /// - public const string NextMarkerElement = "NextMarker"; - - /// - /// XML element for the next partition key. - /// - public const string NextPartitionKeyElement = "NextPartitionKey"; - - /// - /// XML element for the next row key. - /// - public const string NextRowKeyElement = "NextRowKey"; - - /// - /// XML element for the next table name. - /// - public const string NextTableNameElement = "NextTableName"; - - /// - /// XML element for the token version. - /// - public const string VersionElement = "Version"; - - /// - /// Stores the current token version value. - /// - public const string CurrentVersion = "2.0"; - - /// - /// XML element for the token type. - /// - public const string TypeElement = "Type"; - - /// - /// Specifies the blob continuation token type. - /// - public const string BlobType = "Blob"; - - /// - /// Specifies the queue continuation token type. - /// - public const string QueueType = "Queue"; - - /// - /// Specifies the table continuation token type. - /// - public const string TableType = "Table"; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/HttpResponseParsers.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/HttpResponseParsers.Common.cs deleted file mode 100644 index ba485063bc1ff..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/HttpResponseParsers.Common.cs +++ /dev/null @@ -1,156 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Net; - using System.Text; - using System.Xml; - using System.Xml.Linq; - - internal static partial class HttpResponseParsers - { - /// - /// Converts a string to UTC time. - /// - /// The string to convert. - /// A UTC representation of the string. - internal static DateTime ToUTCTime(this string str) - { - return DateTime.Parse( - str, - System.Globalization.DateTimeFormatInfo.InvariantInfo, - System.Globalization.DateTimeStyles.AdjustToUniversal); - } - - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode expectedStatusCode, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase cmd, Exception ex) - { - if (ex != null) - { - throw ex; - } - - if (actualStatusCode != expectedStatusCode) - { - throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.InvariantCulture, SR.UnexpectedResponseCode, expectedStatusCode, actualStatusCode), null); - } - - return retVal; - } - - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode[] expectedStatusCodes, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase cmd, Exception ex) - { - if (ex != null) - { - throw ex; - } - - bool foundExpectedStatusCode = false; - StringBuilder expectedStatusCodeString = null; - foreach (HttpStatusCode expectedStatusCode in expectedStatusCodes) - { - if (actualStatusCode == expectedStatusCode) - { - foundExpectedStatusCode = true; - break; - } - - expectedStatusCodeString.Append(expectedStatusCode); - expectedStatusCodeString.Append(","); - } - - if (!foundExpectedStatusCode) - { - throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.InvariantCulture, SR.UnexpectedResponseCode, expectedStatusCodeString.ToString().TrimEnd(','), actualStatusCode.ToString()), null); - } - - return retVal; - } - - internal static void ValidateResponseStreamMd5AndLength(long? length, string md5, StorageCommandBase cmd) - { - if (cmd.StreamCopyState == null) - { - throw new StorageException( - cmd.CurrentResult, - SR.ContentMD5NotCalculated, - null) - { - IsRetryable = false - }; - } - - if (length.HasValue && (cmd.StreamCopyState.Length != length.Value)) - { - throw new StorageException( - cmd.CurrentResult, - string.Format(CultureInfo.InvariantCulture, SR.IncorrectNumberOfBytes, length, cmd.StreamCopyState.Length), - null) - { - IsRetryable = false - }; - } - - if ((md5 != null) && (cmd.StreamCopyState.Md5 != null) && (cmd.StreamCopyState.Md5 != md5)) - { - throw new StorageException( - cmd.CurrentResult, - SR.MD5MismatchError, - null) - { - IsRetryable = false - }; - } - } - - /// - /// Reads service properties from a stream. - /// - /// The stream from which to read the service properties. - /// The service properties stored in the stream. - internal static ServiceProperties ReadServiceProperties(Stream inputStream) - { - using (XmlReader reader = XmlReader.Create(inputStream)) - { - XDocument servicePropertyDocument = XDocument.Load(reader); - - return ServiceProperties.FromServiceXml(servicePropertyDocument); - } - } - - /// - /// Reads a collection of shared access policies from the specified object. - /// - /// A collection of shared access policies to be filled. - /// A policy response object for reading the stream. - /// The type of policy to read. - internal static void ReadSharedAccessIdentifiers(IDictionary sharedAccessPolicies, AccessPolicyResponseBase policyResponse) - where T : new() - { - foreach (KeyValuePair pair in policyResponse.AccessIdentifiers) - { - sharedAccessPolicies.Add(pair.Key, pair.Value); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ListingContext.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ListingContext.cs deleted file mode 100644 index 5c301f3ba1d0d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ListingContext.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - /// - /// Represents the listing context for enumeration operations. - /// -#if WINDOWS_RT - internal -#else - public -#endif - class ListingContext - { - /// - /// Initializes a new instance of the class. - /// - /// The resource name prefix. - /// The maximum number of resources to return in a single operation, up to the per-operation limit of 5000. - public ListingContext(string prefix, int? maxResults) - { - this.Prefix = prefix; - this.MaxResults = maxResults; - this.Marker = null; - } - - /// - /// Gets or sets the Prefix value. - /// - /// The Prefix value. - public string Prefix { get; set; } - - /// - /// Gets or sets the MaxResults value. - /// - /// The MaxResults value. - public int? MaxResults { get; set; } - - /// - /// Gets or sets the Marker value. - /// - /// The Marker value. - public string Marker { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingOperations.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingOperations.cs deleted file mode 100644 index 88c843c07897b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingOperations.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - - /// - /// Enumeration representing the state of logging in a service. - /// - [Flags] - public enum LoggingOperations - { - /// - /// Logging is disabled. - /// - None = 0x0, - - /// - /// Log read operations. - /// - Read = 0x1, - - /// - /// Log write operations. - /// - Write = 0x2, - - /// - /// Log delete operations. - /// - Delete = 0x4, - - /// - /// Log all operations. - /// - All = 0x7 - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingProperties.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingProperties.cs deleted file mode 100644 index 7539f1d6f97e5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/LoggingProperties.cs +++ /dev/null @@ -1,55 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - /// - /// Class representing the service properties pertaining to logging. - /// - public sealed class LoggingProperties - { - /// - /// Gets or sets the version of the analytics service. - /// - /// A string identifying the version of the service. - public string Version - { - get; - set; - } - - /// - /// Gets or sets the state of logging. - /// - /// A combination of flags describing the operations that are logged. - public LoggingOperations LoggingOperations - { - get; - set; - } - - /// - /// Gets or sets the logging retention policy. - /// - /// The number of days to retain the logs. - public int? RetentionDays - { - get; - set; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsLevel.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsLevel.cs deleted file mode 100644 index 357ff33a81b73..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsLevel.cs +++ /dev/null @@ -1,40 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - /// - /// Enumeration representing the state of metrics collection in a service. - /// - public enum MetricsLevel - { - /// - /// Metrics collection is disabled. - /// - None = 0, - - /// - /// Service-level metrics collection is enabled. - /// - Service, - - /// - /// Service-level and API metrics collection are enabled. - /// - ServiceAndApi - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsProperties.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsProperties.cs deleted file mode 100644 index 6e073b9f9854b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/MetricsProperties.cs +++ /dev/null @@ -1,55 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - /// - /// Class representing the service properties pertaining to metrics. - /// - public sealed class MetricsProperties - { - /// - /// Gets or sets the version of the analytics service. - /// - /// A string identifying the version of the service. - public string Version - { - get; - set; - } - - /// - /// Gets or sets the state of metrics collection. - /// - /// A value indicating which metrics to collect, if any. - public MetricsLevel MetricsLevel - { - get; - set; - } - - /// - /// Gets or sets the logging retention policy. - /// - /// The number of days to retain the logs. - public int? RetentionDays - { - get; - set; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Request.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Request.cs deleted file mode 100644 index c5c5573184127..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Request.cs +++ /dev/null @@ -1,83 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Text; - using System.Xml; - - internal static class Request - { - /// - /// Writes a collection of shared access policies to the specified stream in XML format. - /// - /// A collection of shared access policies. - /// An output stream. - /// A delegate that writes a policy to an XML writer. - /// The type of policy to write. - internal static void WriteSharedAccessIdentifiers(IDictionary sharedAccessPolicies, Stream outputStream, Action writePolicyXml) - { - CommonUtility.AssertNotNull("sharedAccessPolicies", sharedAccessPolicies); - CommonUtility.AssertNotNull("outputStream", outputStream); - - if (sharedAccessPolicies.Count > Constants.MaxSharedAccessPolicyIdentifiers) - { - string errorMessage = string.Format( - CultureInfo.CurrentCulture, - SR.TooManyPolicyIdentifiers, - sharedAccessPolicies.Count, - Constants.MaxSharedAccessPolicyIdentifiers); - - throw new ArgumentOutOfRangeException("sharedAccessPolicies", errorMessage); - } - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = Encoding.UTF8; - - using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) - { - writer.WriteStartElement(Constants.SignedIdentifiers); - - foreach (string key in sharedAccessPolicies.Keys) - { - writer.WriteStartElement(Constants.SignedIdentifier); - - // Set the identifier - writer.WriteElementString(Constants.Id, key); - - // Set the permissions - writer.WriteStartElement(Constants.AccessPolicy); - - T policy = sharedAccessPolicies[key]; - - writePolicyXml(policy, writer); - - writer.WriteEndElement(); // AccessPolicy - writer.WriteEndElement(); // SignedIdentifier - } - - writer.WriteEndDocument(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Response.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Response.cs deleted file mode 100644 index 79e67d2848ca7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/Response.cs +++ /dev/null @@ -1,91 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.Collections.Generic; - using System.Net; - using System.Xml; - - internal static class Response - { -#if WINDOWS_DESKTOP - /// - /// Gets the request id. - /// - /// The response from server. - /// The request ID. - internal static string GetRequestId(HttpWebResponse response) - { - return response.Headers[Constants.HeaderConstants.RequestIdHeader]; - } -#endif - - /// - /// Reads a collection of shared access policies from the specified object. - /// - /// A collection of shared access policies to be filled. - /// A policy response object for reading the stream. - /// The type of policy to read. - internal static void ReadSharedAccessIdentifiers(IDictionary sharedAccessPolicies, AccessPolicyResponseBase policyResponse) - where T : new() - { - foreach (KeyValuePair pair in policyResponse.AccessIdentifiers) - { - sharedAccessPolicies.Add(pair.Key, pair.Value); - } - } - - /// - /// Parses the metadata. - /// - /// The reader. - /// A of metadata. - /// - /// Precondition: reader at <Metadata> - /// Postcondition: reader after </Metadata> (<Metadata/> consumed) - /// - internal static IDictionary ParseMetadata(XmlReader reader) - { - IDictionary metadata = new Dictionary(); - bool needToRead = true; - while (true) - { - if (needToRead && !reader.Read()) - { - return metadata; - } - - if (reader.NodeType == XmlNodeType.Element && !reader.IsEmptyElement) - { - needToRead = false; - string elementName = reader.Name; - string elementValue = reader.ReadElementContentAsString(); - if (elementName != Constants.InvalidMetadataName) - { - metadata.Add(elementName, elementValue); - } - } - else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == Constants.MetadataElement) - { - reader.Read(); - return metadata; - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ResponseParsingBase.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ResponseParsingBase.cs deleted file mode 100644 index cc5aa6ac37544..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ResponseParsingBase.cs +++ /dev/null @@ -1,206 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Xml; - - /// - /// Provides a base class that is used internally to parse XML streams from storage service operations. - /// - /// The type to be parsed. - [EditorBrowsable(EditorBrowsableState.Never)] -#if WINDOWS_RT - internal -#else - public -#endif - abstract class ResponseParsingBase : IDisposable - { - /// - /// Indicates that all parsable objects have been consumed. This field is reserved and should not be used. - /// - [SuppressMessage( - "Microsoft.StyleCop.CSharp.MaintainabilityRules", - "SA1401:FieldsMustBePrivate", - Justification = "Unable to change while remaining backwards compatible.")] - protected bool allObjectsParsed; - - /// - /// Stores any objects that have not yet been parsed. This field is reserved and should not be used. - /// - [SuppressMessage( - "Microsoft.StyleCop.CSharp.MaintainabilityRules", - "SA1401:FieldsMustBePrivate", - Justification = "Unable to change while remaining backwards compatible.")] - protected IList outstandingObjectsToParse = new List(); - - /// - /// The reader used for parsing. This field is reserved and should not be used. - /// - [SuppressMessage( - "Microsoft.StyleCop.CSharp.MaintainabilityRules", - "SA1401:FieldsMustBePrivate", - Justification = "Unable to change while remaining backwards compatible.")] - protected XmlReader reader; - - /// - /// The IEnumerator over the parsed content. - /// - private IEnumerator parser; - - /// - /// Used to make sure that parsing is only done once, since a stream is not re-entrant. - /// - private bool enumerableConsumed; - - /// - /// Initializes a new instance of the ResponseParsingBase class. - /// - /// The stream to be parsed. - protected ResponseParsingBase(Stream stream) - { - XmlReaderSettings readerSettings = new XmlReaderSettings(); - readerSettings.IgnoreWhitespace = false; - this.reader = XmlReader.Create(stream, readerSettings); - this.parser = this.ParseXmlAndClose().GetEnumerator(); - } - - /// - /// Gets the parsable objects. This method is reserved and should not be used. - /// - /// The objects to parse. - protected IEnumerable ObjectsToParse - { - get - { - if (this.enumerableConsumed) - { - throw new InvalidOperationException(SR.ResourceConsumed); - } - - this.enumerableConsumed = true; - - while (!this.allObjectsParsed && this.parser.MoveNext()) - { - if (this.parser.Current != null) - { - yield return this.parser.Current; - } - } - - foreach (T parsableObject in this.outstandingObjectsToParse) - { - yield return parsableObject; - } - - this.outstandingObjectsToParse = null; - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - this.Dispose(true); - - GC.SuppressFinalize(this); - } - - /// - /// Parses the XML response. This method is reserved and should not be used. - /// - /// A collection of enumerable objects. - protected abstract IEnumerable ParseXml(); - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources, and optional - /// managed resources. - /// - /// True to release both managed and unmanaged resources; otherwise, false. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (this.reader != null) - { -#if WINDOWS_RT - this.reader.Dispose(); -#else - this.reader.Close(); -#endif - } - } - - this.reader = null; - } - - /// - /// This method is reserved and should not be used. - /// - /// True when the object is consumable. - [SuppressMessage( - "Microsoft.Design", - "CA1045:DoNotPassTypesByReference", - MessageId = "0#", - Justification = "The consumable flag needs to be referenced so updates will propagate to this method.")] - protected void Variable(ref bool consumable) - { - if (!consumable) - { - while (this.parser.MoveNext()) - { - if (this.parser.Current != null) - { - this.outstandingObjectsToParse.Add(this.parser.Current); - } - - if (consumable) - { - break; - } - } - } - } - - /// - /// Parses the XML and close. - /// - /// A list of parsed results. - private IEnumerable ParseXmlAndClose() - { - foreach (T item in this.ParseXml()) - { - yield return item; - } - -#if WINDOWS_RT - this.reader.Dispose(); -#else - this.reader.Close(); -#endif - this.reader = null; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ServiceProperties.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ServiceProperties.cs deleted file mode 100644 index 7acabd64515d4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/ServiceProperties.cs +++ /dev/null @@ -1,348 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Globalization; - using System.IO; - using System.Text; - using System.Xml; - using System.Xml.Linq; - - /// - /// Class representing a set of properties pertaining to a cloud storage service. - /// - public sealed class ServiceProperties - { - /// - /// The name of the root XML element. - /// - internal const string StorageServicePropertiesName = "StorageServiceProperties"; - - /// - /// The name of the logging XML element. - /// - internal const string LoggingName = "Logging"; - - /// - /// The name of the metrics XML element. - /// - internal const string MetricsName = "Metrics"; - - /// - /// The name of the version XML element. - /// - internal const string VersionName = "Version"; - - /// - /// The name of the delete operation XML element. - /// - internal const string DeleteName = "Delete"; - - /// - /// The name of the read operation XML element. - /// - internal const string ReadName = "Read"; - - /// - /// The name of the write operation XML element. - /// - internal const string WriteName = "Write"; - - /// - /// The name of the retention policy XML element. - /// - internal const string RetentionPolicyName = "RetentionPolicy"; - - /// - /// The name of the enabled XML element. - /// - internal const string EnabledName = "Enabled"; - - /// - /// The name of the days XML element. - /// - internal const string DaysName = "Days"; - - /// - /// The name of the include APIs XML element. - /// - internal const string IncludeApisName = "IncludeAPIs"; - - /// - /// The name of the default service version XML element. - /// - internal const string DefaultServiceVersionName = "DefaultServiceVersion"; - - /// - /// Initializes a new instance of the ServiceProperties class. - /// - public ServiceProperties() - { - this.Logging = new LoggingProperties(); - this.Metrics = new MetricsProperties(); - } - - /// - /// Gets or sets the logging properties. - /// - /// The logging properties. - public LoggingProperties Logging - { - get; - set; - } - - /// - /// Gets or sets the metrics properties. - /// - /// The metrics properties. - public MetricsProperties Metrics - { - get; - set; - } - - /// - /// Gets or sets the default service version. - /// - /// The default service version identifier. - public string DefaultServiceVersion - { - get; - set; - } - - /// - /// Constructs a ServiceProperties object from an XML document received from the service. - /// - /// The XML document. - /// A ServiceProperties object containing the properties in the XML document. - internal static ServiceProperties FromServiceXml(XDocument servicePropertiesDocument) - { - XElement servicePropertiesElement = servicePropertiesDocument.Element(StorageServicePropertiesName); - ServiceProperties properties = new ServiceProperties() - { - Logging = ReadLoggingPropertiesFromXml(servicePropertiesElement.Element(LoggingName)), - Metrics = ReadMetricsPropertiesFromXml(servicePropertiesElement.Element(MetricsName)) - }; - - XElement defaultServiceVersionXml = servicePropertiesElement.Element(DefaultServiceVersionName); - if (defaultServiceVersionXml != null) - { - properties.DefaultServiceVersion = defaultServiceVersionXml.Value; - } - - return properties; - } - - /// - /// Converts these properties into XML for communicating with the service. - /// - /// An XML document containing the service properties. - internal XDocument ToServiceXml() - { - CommonUtility.AssertNotNull("Logging", this.Logging); - CommonUtility.AssertNotNull("Metrics", this.Metrics); - - XElement storageServiceElement = new XElement( - StorageServicePropertiesName, - GenerateLoggingXml(this.Logging), - GenerateMetricsXml(this.Metrics)); - - if (this.DefaultServiceVersion != null) - { - storageServiceElement.Add(new XElement(DefaultServiceVersionName, this.DefaultServiceVersion)); - } - - return new XDocument(storageServiceElement); - } - - /// - /// Generates XML representing the given retention policy. - /// - /// The number of days to retain, or null if the policy is disabled. - /// An XML retention policy element. - private static XElement GenerateRetentionPolicyXml(int? retentionDays) - { - bool enabled = retentionDays != null; - XElement xml = new XElement(RetentionPolicyName, new XElement(EnabledName, enabled)); - - if (enabled) - { - xml.Add(new XElement(DaysName, (int)retentionDays)); - } - - return xml; - } - - /// - /// Generates XML representing the given metrics properties. - /// - /// The metrics properties. - /// An XML metrics element. - private static XElement GenerateMetricsXml(MetricsProperties metrics) - { - if (!Enum.IsDefined(typeof(MetricsLevel), metrics.MetricsLevel)) - { - throw new InvalidOperationException(SR.InvalidMetricsLevel); - } - - if (string.IsNullOrEmpty(metrics.Version)) - { - throw new InvalidOperationException(SR.MetricVersionNull); - } - - bool enabled = metrics.MetricsLevel != MetricsLevel.None; - - XElement xml = new XElement( - MetricsName, - new XElement(VersionName, metrics.Version), - new XElement(EnabledName, enabled), - GenerateRetentionPolicyXml(metrics.RetentionDays)); - - if (enabled) - { - xml.Add(new XElement(IncludeApisName, metrics.MetricsLevel == MetricsLevel.ServiceAndApi)); - } - - return xml; - } - - /// - /// Generates XML representing the given logging properties. - /// - /// The logging properties. - /// An XML logging element. - private static XElement GenerateLoggingXml(LoggingProperties logging) - { - if ((LoggingOperations.All & logging.LoggingOperations) != logging.LoggingOperations) - { - throw new InvalidOperationException(SR.InvalidLoggingLevel); - } - - if (string.IsNullOrEmpty(logging.Version)) - { - throw new InvalidOperationException(SR.LoggingVersionNull); - } - - return new XElement( - LoggingName, - new XElement(VersionName, logging.Version), - new XElement(DeleteName, (logging.LoggingOperations & LoggingOperations.Delete) != 0), - new XElement(ReadName, (logging.LoggingOperations & LoggingOperations.Read) != 0), - new XElement(WriteName, (logging.LoggingOperations & LoggingOperations.Write) != 0), - GenerateRetentionPolicyXml(logging.RetentionDays)); - } - - /// - /// Constructs a LoggingProperties object from an XML element. - /// - /// The XML element. - /// A LoggingProperties object containing the properties in the element. - private static LoggingProperties ReadLoggingPropertiesFromXml(XElement element) - { - LoggingOperations state = LoggingOperations.None; - - if (bool.Parse(element.Element(DeleteName).Value)) - { - state |= LoggingOperations.Delete; - } - - if (bool.Parse(element.Element(ReadName).Value)) - { - state |= LoggingOperations.Read; - } - - if (bool.Parse(element.Element(WriteName).Value)) - { - state |= LoggingOperations.Write; - } - - return new LoggingProperties() - { - Version = element.Element(VersionName).Value, - LoggingOperations = state, - RetentionDays = ReadRetentionPolicyFromXml(element.Element(RetentionPolicyName)) - }; - } - - /// - /// Constructs a MetricsProperties object from an XML element. - /// - /// The XML element. - /// A MetricsProperties object containing the properties in the element. - private static MetricsProperties ReadMetricsPropertiesFromXml(XElement element) - { - MetricsLevel state = MetricsLevel.None; - - if (bool.Parse(element.Element(EnabledName).Value)) - { - state = MetricsLevel.Service; - - if (bool.Parse(element.Element(IncludeApisName).Value)) - { - state = MetricsLevel.ServiceAndApi; - } - } - - return new MetricsProperties() - { - Version = element.Element(VersionName).Value, - MetricsLevel = state, - RetentionDays = ReadRetentionPolicyFromXml(element.Element(RetentionPolicyName)) - }; - } - - /// - /// Constructs a retention policy (number of days) from an XML element. - /// - /// The XML element. - /// The number of days to retain, or null if retention is disabled. - private static int? ReadRetentionPolicyFromXml(XElement element) - { - if (!bool.Parse(element.Element(EnabledName).Value)) - { - return null; - } - else - { - return int.Parse(element.Element(DaysName).Value, CultureInfo.InvariantCulture); - } - } - - /// - /// Writes service properties to a stream, formatted in XML. - /// - /// The stream to which the formatted properties are to be written. - internal void WriteServiceProperties(Stream outputStream) - { - XDocument propertiesDocument = this.ToServiceXml(); - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Encoding = Encoding.UTF8; - settings.NewLineHandling = NewLineHandling.Entitize; - - using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) - { - propertiesDocument.Save(writer); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/StorageErrorCodeStrings.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/StorageErrorCodeStrings.cs deleted file mode 100644 index a9ea547ec243b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Shared/Protocol/StorageErrorCodeStrings.cs +++ /dev/null @@ -1,212 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Provides error code strings that are common to all storage services. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class StorageErrorCodeStrings - { - /// - /// The specified HTTP verb is not supported. - /// - public const string UnsupportedHttpVerb = "UnsupportedHttpVerb"; - - /// - /// The Content-Length header is required for this request. - /// - public const string MissingContentLengthHeader = "MissingContentLengthHeader"; - - /// - /// A required header was missing. - /// - public const string MissingRequiredHeader = "MissingRequiredHeader"; - - /// - /// A required XML node was missing. - /// - public const string MissingRequiredXmlNode = "MissingRequiredXmlNode"; - - /// - /// One or more header values are not supported. - /// - public const string UnsupportedHeader = "UnsupportedHeader"; - - /// - /// One or more XML nodes are not supported. - /// - public const string UnsupportedXmlNode = "UnsupportedXmlNode"; - - /// - /// One or more header values are invalid. - /// - public const string InvalidHeaderValue = "InvalidHeaderValue"; - - /// - /// One or more XML node values are invalid. - /// - public const string InvalidXmlNodeValue = "InvalidXmlNodeValue"; - - /// - /// A required query parameter is missing. - /// - public const string MissingRequiredQueryParameter = "MissingRequiredQueryParameter"; - - /// - /// One or more query parameters is not supported. - /// - public const string UnsupportedQueryParameter = "UnsupportedQueryParameter"; - - /// - /// One or more query parameters are invalid. - /// - public const string InvalidQueryParameterValue = "InvalidQueryParameterValue"; - - /// - /// One or more query parameters are out of range. - /// - public const string OutOfRangeQueryParameterValue = "OutOfRangeQueryParameterValue"; - - /// - /// The URI is invalid. - /// - public const string InvalidUri = "InvalidUri"; - - /// - /// The HTTP verb is invalid. - /// - public const string InvalidHttpVerb = "InvalidHttpVerb"; - - /// - /// The metadata key is empty. - /// - public const string EmptyMetadataKey = "EmptyMetadataKey"; - - /// - /// The request body is too large. - /// - public const string RequestBodyTooLarge = "RequestBodyTooLarge"; - - /// - /// The specified XML document is invalid. - /// - public const string InvalidXmlDocument = "InvalidXmlDocument"; - - /// - /// An internal error occurred. - /// - public const string InternalError = "InternalError"; - - /// - /// Authentication failed. - /// - public const string AuthenticationFailed = "AuthenticationFailed"; - - /// - /// The specified MD5 hash does not match the server value. - /// - [SuppressMessage( - "Microsoft.Naming", - "CA1709:IdentifiersShouldBeCasedCorrectly", - MessageId = "Md", - Justification = "The casing matches the storage constant the identifier represents.")] - public const string Md5Mismatch = "Md5Mismatch"; - - /// - /// The specified MD5 hash is invalid. - /// - [SuppressMessage( - "Microsoft.Naming", - "CA1709:IdentifiersShouldBeCasedCorrectly", - MessageId = "Md", - Justification = "The casing matches the storage constant the identifier represents.")] - public const string InvalidMd5 = "InvalidMd5"; - - /// - /// The input is out of range. - /// - public const string OutOfRangeInput = "OutOfRangeInput"; - - /// - /// The input is invalid. - /// - public const string InvalidInput = "InvalidInput"; - - /// - /// The operation timed out. - /// - public const string OperationTimedOut = "OperationTimedOut"; - - /// - /// The specified resource was not found. - /// - public const string ResourceNotFound = "ResourceNotFound"; - - /// - /// The specified metadata is invalid. - /// - public const string InvalidMetadata = "InvalidMetadata"; - - /// - /// The specified metadata is too large. - /// - public const string MetadataTooLarge = "MetadataTooLarge"; - - /// - /// The specified condition was not met. - /// - public const string ConditionNotMet = "ConditionNotMet"; - - /// - /// The specified range is invalid. - /// - public const string InvalidRange = "InvalidRange"; - - /// - /// The specified container was not found. - /// - public const string ContainerNotFound = "ContainerNotFound"; - - /// - /// The specified container already exists. - /// - public const string ContainerAlreadyExists = "ContainerAlreadyExists"; - - /// - /// The specified container is disabled. - /// - public const string ContainerDisabled = "ContainerDisabled"; - - /// - /// The specified container is being deleted. - /// - public const string ContainerBeingDeleted = "ContainerBeingDeleted"; - - /// - /// The server is busy. - /// - public const string ServerBusy = "ServerBusy"; - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/StorageException.cs b/microsoft-azure-api/Services/Storage/Lib/Common/StorageException.cs deleted file mode 100644 index 6b3e7928b7475..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/StorageException.cs +++ /dev/null @@ -1,245 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Net; - using System.Text; - -#if WINDOWS_DESKTOP - using System.Runtime.Serialization; -#elif WINDOWS_RT - using System.IO; - using System.Runtime.InteropServices; -#endif - - /// - /// Represents an exception thrown by the Windows Azure storage service. - /// -#if !WINDOWS_RT && !WINDOWS_PHONE - [Serializable] -#endif - -#if WINDOWS_RT - internal class StorageException : COMException -#else - public class StorageException : Exception -#endif - { - /// - /// Gets the object for this object. - /// - /// The object for this object. - public RequestResult RequestInformation { get; private set; } - - internal bool IsRetryable { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public StorageException() : this(null /* res */, null /* message */, null /* inner */) - { - } - - /// - /// Initializes a new instance of the class using the specified error message. - /// - /// The message that describes the error. - public StorageException(string message) : - this(null /* res */, message, null /* inner */) - { - } - - /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that generated this exception. - /// - /// The exception error message. - /// The inner exception. - public StorageException(string message, Exception innerException) : - this(null /* res */, message, innerException) - { - } - -#if !WINDOWS_RT && !WINDOWS_PHONE - /// - /// Initializes a new instance of the class with serialized data. - /// - /// The that contains contextual information about the source or destination. - /// The object that holds serialized object data for the exception being thrown. - /// This constructor is called during de-serialization to reconstitute the exception object transmitted over a stream. - protected StorageException(SerializationInfo info, StreamingContext context) : - base(info, context) - { - if (info != null) - { - this.IsRetryable = info.GetBoolean("IsRetryable"); - this.RequestInformation = (RequestResult)info.GetValue("RequestInformation", typeof(RequestResult)); - } - } - - /// - /// Populates a object with the data needed to serialize the target object. - /// - /// The destination context for this serialization. - /// The object to populate with data. - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info != null) - { - info.AddValue("IsRetryable", this.IsRetryable); - info.AddValue("RequestInformation", this.RequestInformation, typeof(RequestResult)); - } - - base.GetObjectData(info, context); - } -#endif - - /// - /// Initializes a new instance of the class by using the specified parameters. - /// - /// The request result. - /// The exception message. - /// The inner exception. - public StorageException(RequestResult res, string message, Exception inner) - : base(message, inner) - { - this.RequestInformation = res; - this.IsRetryable = true; - } - - /// - /// Translates the specified exception into a . - /// - /// The exception to translate. - /// The request result. - /// An exception of type . - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "General Exception wrapped as a StorageException.")] - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code clarity.")] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "req", Justification = "Reviewed : req is allowed.")] - public static StorageException TranslateException(Exception ex, RequestResult reqResult) - { - CommonUtility.AssertNotNull("reqResult", reqResult); - CommonUtility.AssertNotNull("ex", ex); - - // Dont re-wrap storage exceptions - if (ex is StorageException) - { - return (StorageException)ex; - } - else if (ex is TimeoutException) - { - reqResult.HttpStatusMessage = null; - reqResult.HttpStatusCode = (int)HttpStatusCode.Unused; - reqResult.ExtendedErrorInformation = null; - return new StorageException(reqResult, ex.Message, ex); - } - else if (ex is ArgumentException) - { - reqResult.HttpStatusMessage = null; - reqResult.HttpStatusCode = (int)HttpStatusCode.Unused; - reqResult.ExtendedErrorInformation = null; - return new StorageException(reqResult, ex.Message, ex) { IsRetryable = false }; - } -#if WINDOWS_RT - else if (ex is OperationCanceledException) - { - reqResult.HttpStatusMessage = null; - reqResult.HttpStatusCode = 306; // unused - reqResult.ExtendedErrorInformation = null; - return new StorageException(reqResult, ex.Message, ex); - } -#elif WINDOWS_DESKTOP && !WINDOWS_PHONE - else - { - StorageException tableEx = TableUtilities.TranslateDataServiceClientException(ex, reqResult); - - if (tableEx != null) - { - return tableEx; - } - } -#endif - - WebException we = ex as WebException; - if (we != null) - { - try - { - HttpWebResponse response = we.Response as HttpWebResponse; - if (response != null) - { - reqResult.HttpStatusMessage = response.StatusDescription; - reqResult.HttpStatusCode = (int)response.StatusCode; - if (response.Headers != null) - { -#if WINDOWS_DESKTOP - reqResult.ServiceRequestID = HttpWebUtility.TryGetHeader(response, Constants.HeaderConstants.RequestIdHeader, null); - reqResult.ContentMd5 = HttpWebUtility.TryGetHeader(response, "Content-MD5", null); - string tempDate = HttpWebUtility.TryGetHeader(response, "Date", null); - reqResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate; - reqResult.Etag = response.Headers[HttpResponseHeader.ETag]; -#endif - } -#if WINDOWS_RT - reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(response.GetResponseStream().AsInputStream()); -#else - reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(response.GetResponseStream()); -#endif - } - } - catch (Exception) - { - // no op - } - } - - // Not WebException, just wrap in StorageException - return new StorageException(reqResult, ex.Message, ex); - } - - /// - /// Represents an exception thrown by the Windows Azure storage client library. - /// - /// A string that represents the exception. - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine(base.ToString()); - - if (this.RequestInformation != null) - { - sb.AppendLine("Request Information"); - sb.AppendLine("RequestID:" + this.RequestInformation.ServiceRequestID); - sb.AppendLine("RequestDate:" + this.RequestInformation.RequestDate); - sb.AppendLine("StatusMessage:" + this.RequestInformation.HttpStatusMessage); - - if (this.RequestInformation.ExtendedErrorInformation != null) - { - sb.AppendLine("ErrorCode:" + this.RequestInformation.ExtendedErrorInformation.ErrorCode); - } - } - - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/StorageExtendedErrorInformation.cs b/microsoft-azure-api/Services/Storage/Lib/Common/StorageExtendedErrorInformation.cs deleted file mode 100644 index f8026cbeed020..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/StorageExtendedErrorInformation.cs +++ /dev/null @@ -1,210 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Xml; - -#if WINDOWS_RT - using Windows.Storage.Streams; -#endif - - /// - /// Represents extended error information returned by the Windows Azure storage services. - /// -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - [Serializable] -#endif - public sealed class StorageExtendedErrorInformation - { - /// - /// Initializes a new instance of the class. - /// - public StorageExtendedErrorInformation() - { - } - - /// - /// Gets the storage service error code. - /// - /// The storage service error code. - public string ErrorCode { get; internal set; } - - /// - /// Gets the storage service error message. - /// - /// The storage service error message. - public string ErrorMessage { get; internal set; } - - /// - /// Gets additional error details. - /// - /// The additional error details. - public IDictionary AdditionalDetails { get; internal set; } - -#if WINDOWS_RT - public static StorageExtendedErrorInformation ReadFromStream(IInputStream inputStream) - { - return ReadFromStream(inputStream.AsStreamForRead()); - } -#endif - - /// - /// Gets the error details from stream. - /// - /// The input stream. - /// The error details. -#if WINDOWS_RT - internal -#else - public -#endif - static StorageExtendedErrorInformation ReadFromStream(Stream inputStream) - { - CommonUtility.AssertNotNull("inputStream", inputStream); - - if (inputStream.CanSeek && inputStream.Length < 1) - { - return null; - } - - StorageExtendedErrorInformation extendedErrorInfo = new StorageExtendedErrorInformation(); - try - { - using (XmlReader reader = XmlReader.Create(inputStream)) - { - reader.Read(); - extendedErrorInfo.ReadXml(reader); - } - - return extendedErrorInfo; - } - catch (XmlException) - { - // If there is a parsing error we cannot return extended error information - return null; - } - } - - #region IXmlSerializable - - /// - /// Generates a serializable object from its XML representation. - /// - /// The stream from which the object is deserialized. -#if WINDOWS_RT - internal -#else - public -#endif - void ReadXml(XmlReader reader) - { - CommonUtility.AssertNotNull("reader", reader); - - this.AdditionalDetails = new Dictionary(); - - reader.ReadStartElement(); - while (reader.IsStartElement()) - { - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - if ((string.Compare(reader.Name, Constants.ErrorCode, StringComparison.Ordinal) == 0) || (string.Compare(reader.Name, Constants.ErrorCodePreview, StringComparison.Ordinal) == 0)) - { - this.ErrorCode = reader.ReadElementContentAsString(); - } - else if ((string.Compare(reader.Name, Constants.ErrorMessage, StringComparison.Ordinal) == 0) || (string.Compare(reader.Name, Constants.ErrorMessagePreview, StringComparison.Ordinal) == 0)) - { - this.ErrorMessage = reader.ReadElementContentAsString(); - } - else if (string.Compare(reader.Name, Constants.ErrorException, StringComparison.Ordinal) == 0) - { - reader.ReadStartElement(); - while (reader.IsStartElement()) - { - switch (reader.Name) - { - case Constants.ErrorExceptionMessage: - this.AdditionalDetails.Add( - Constants.ErrorExceptionMessage, - reader.ReadElementContentAsString(Constants.ErrorExceptionMessage, string.Empty)); - break; - - case Constants.ErrorExceptionStackTrace: - this.AdditionalDetails.Add( - Constants.ErrorExceptionStackTrace, - reader.ReadElementContentAsString(Constants.ErrorExceptionStackTrace, string.Empty)); - break; - - default: - reader.Skip(); - break; - } - } - - reader.ReadEndElement(); - } - else - { - this.AdditionalDetails.Add( - reader.Name, - reader.ReadInnerXml()); - } - } - } - - reader.ReadEndElement(); - } - - /// - /// Converts a serializable object into its XML representation. - /// - /// The stream to which the object is serialized. -#if WINDOWS_RT - internal -#else - public -#endif - void WriteXml(XmlWriter writer) - { - CommonUtility.AssertNotNull("writer", writer); - - writer.WriteStartElement(Constants.ErrorRootElement); - writer.WriteElementString(Constants.ErrorCode, this.ErrorCode); - writer.WriteElementString(Constants.ErrorMessage, this.ErrorMessage); - - foreach (string key in this.AdditionalDetails.Keys) - { - writer.WriteElementString(key, this.AdditionalDetails[key]); - } - - // End StorageExtendedErrorInformation - writer.WriteEndElement(); - } - - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTable.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTable.Common.cs deleted file mode 100644 index 6e22bd6cfeb7a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTable.Common.cs +++ /dev/null @@ -1,179 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Represents a Windows Azure table. - /// - public sealed partial class CloudTable - { - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the table. - public CloudTable(Uri tableAddress) - : this(tableAddress, null /* credentials */) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The absolute URI to the table. - /// The account credentials. - public CloudTable(Uri tableAbsoluteUri, StorageCredentials credentials) - { - this.ParseQueryAndVerify(tableAbsoluteUri, credentials); - } - - /// - /// Initializes a new instance of the class. - /// - /// The table name. - /// The client. - internal CloudTable(string tableName, CloudTableClient client) - { - CommonUtility.AssertNotNull("tableName", tableName); - CommonUtility.AssertNotNull("client", client); - this.Name = tableName; - this.Uri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - this.ServiceClient = client; - } - - /// - /// Gets the object that represents the Table service. - /// - /// A client object that specifies the Table service endpoint. - public CloudTableClient ServiceClient { get; private set; } - - /// - /// Gets the table name. - /// - /// The table name. - public string Name { get; private set; } - - /// - /// Gets the URI that identifies the table. - /// - /// The address of the table. - public Uri Uri { get; private set; } - - /// - /// Returns a shared access signature for the table. - /// - /// The access policy for the shared access signature. - /// An access policy identifier. - /// The start partition key, or null. - /// The start row key, or null. - /// The end partition key, or null. - /// The end row key, or null. - /// A shared access signature, as a URI query string. - /// The query string returned includes the leading question mark. - /// Thrown if the current credentials don't support creating a shared access signature. - public string GetSharedAccessSignature( - SharedAccessTablePolicy policy, - string accessPolicyIdentifier, - string startPartitionKey, - string startRowKey, - string endPartitionKey, - string endRowKey) - { - if (!this.ServiceClient.Credentials.IsSharedKey) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.CannotCreateSASWithoutAccountKey); - throw new InvalidOperationException(errorMessage); - } - - string resourceName = this.GetCanonicalName(); - StorageAccountKey accountKey = this.ServiceClient.Credentials.Key; - - string signature = SharedAccessSignatureHelper.GetSharedAccessSignatureHashImpl( - policy, - accessPolicyIdentifier, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - resourceName, - accountKey.KeyValue); - - UriQueryBuilder builder = SharedAccessSignatureHelper.GetSharedAccessSignatureImpl( - policy, - this.Name, - accessPolicyIdentifier, - startPartitionKey, - startRowKey, - endPartitionKey, - endRowKey, - signature, - accountKey.KeyName); - - return builder.ToString(); - } - - /// - /// Returns the name of the table. - /// - /// The name of the table. - public override string ToString() - { - return this.Name; - } - - /// - /// Parse URI for SAS (Shared Access Signature) information. - /// - /// The complete Uri. - /// The credentials to use. - private void ParseQueryAndVerify(Uri address, StorageCredentials credentials) - { - StorageCredentials parsedCredentials; - this.Uri = NavigationHelper.ParseQueueTableQueryAndVerify(address, out parsedCredentials); - - if ((parsedCredentials != null) && (credentials != null) && !parsedCredentials.Equals(credentials)) - { - string error = string.Format(CultureInfo.CurrentCulture, SR.MultipleCredentialsProvided); - throw new ArgumentException(error); - } - - this.ServiceClient = new CloudTableClient(NavigationHelper.GetServiceClientBaseAddress(this.Uri, null), credentials ?? parsedCredentials); - this.Name = NavigationHelper.GetTableNameFromUri(this.Uri, this.ServiceClient.UsePathStyleUris); - } - - /// - /// Gets the canonical name of the table, formatted as /<account-name>/<table-name>. - /// - /// The canonical name of the table. - [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "ToLower(CultureInfo) is not present in RT and ToLowerInvariant() also violates FxCop")] - private string GetCanonicalName() - { - string accountName = this.ServiceClient.Credentials.AccountName; - string tableNameLowerCase = this.Name.ToLower(); - - return string.Format(CultureInfo.InvariantCulture, "/{0}/{1}", accountName, tableNameLowerCase); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTableClient.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTableClient.Common.cs deleted file mode 100644 index 79c0ff7865578..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/CloudTableClient.Common.cs +++ /dev/null @@ -1,206 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Globalization; - - /// - /// Provides a client-side logical representation of the Windows Azure Table service. This client is used to configure and execute requests against the Table service. - /// - /// The CloudTableClient object encapsulates the base URI for the Table service. If the service client will be used for authenticated access, - /// it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudTableClient - { - /// - /// The default server and client timeout interval. - /// - private TimeSpan? timeout; - - /// - /// Max execution time across all potential retries. - /// - private TimeSpan? maximumExecutionTime; - - private AuthenticationScheme authenticationScheme; - - /// - /// Initializes a new instance of the class using the specified Table service endpoint - /// and anonymous credentials. - /// - /// The Table service endpoint to use to create the client. - public CloudTableClient(Uri baseUri) - : this(baseUri, null) - { - } - - /// - /// Initializes a new instance of the class using the specified Table service endpoint - /// and storage account credentials. - /// - /// The Table service endpoint to use to create the client. - /// The storage account credentials. - public CloudTableClient(Uri baseUri, StorageCredentials credentials) - : this(null, baseUri, credentials) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// True to use path-style URIs. - /// The Table service endpoint to use to create the client. - /// The storage account credentials. - internal CloudTableClient(bool? usePathStyleUris, Uri baseUri, StorageCredentials credentials) - { - CommonUtility.AssertNotNull("baseUri", baseUri); - - if (credentials == null) - { - credentials = new StorageCredentials(); - } - - if (!baseUri.IsAbsoluteUri) - { - string errorMessage = string.Format( - CultureInfo.CurrentCulture, - SR.RelativeAddressNotPermitted, - baseUri.ToString()); - - throw new ArgumentException(errorMessage, "baseUri"); - } - - this.BaseUri = baseUri; - this.Credentials = credentials; - this.RetryPolicy = new ExponentialRetry(); - this.ServerTimeout = Constants.DefaultServerSideTimeout; - this.AuthenticationScheme = AuthenticationScheme.SharedKey; - - if (usePathStyleUris.HasValue) - { - this.UsePathStyleUris = usePathStyleUris.Value; - } - else - { - // Automatically decide whether to use host style uri or path style uri - this.UsePathStyleUris = CommonUtility.UsePathStyleAddressing(this.BaseUri); - } - } - - /// - /// Gets or sets a buffer manager that implements the interface, - /// specifying a buffer pool for use with operations against the Table service client. - /// - public IBufferManager BufferManager { get; set; } - - /// - /// Gets the storage account credentials used to create the Table service client. - /// - /// The storage account credentials. - public StorageCredentials Credentials { get; private set; } - - /// - /// Gets the base URI for the Table service client. - /// - /// The base URI used to construct the Table service client. - public Uri BaseUri { get; private set; } - - /// - /// Gets or sets the default retry policy for requests made via the Table service client. - /// - /// The retry policy. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the default server and client timeout for requests. - /// - /// The server and client timeout interval. - public TimeSpan? ServerTimeout - { - get - { - return this.timeout; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.timeout = value; - } - } - - /// - /// Gets or sets the maximum execution time across all potential retries. - /// - /// The maximum execution time across all potential retries. - public TimeSpan? MaximumExecutionTime - { - get - { - return this.maximumExecutionTime; - } - - set - { - if (value.HasValue) - { - CommonUtility.CheckTimeoutBounds(value.Value); - } - - this.maximumExecutionTime = value; - } - } - - /// - /// Gets a value indicating whether the service client is used with Path style or Host style. - /// - /// Is true if use path style URIs; otherwise, false. - internal bool UsePathStyleUris { get; private set; } - - /// - /// Gets a reference to the specified table. - /// - /// The name of the table. - /// A object. - public CloudTable GetTableReference(string tableName) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - return new CloudTable(tableName, this); - } - - private ICanonicalizer GetCanonicalizer() - { - if (this.AuthenticationScheme == AuthenticationScheme.SharedKeyLite) - { - return SharedKeyLiteTableCanonicalizer.Instance; - } - - return SharedKeyTableCanonicalizer.Instance; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/DynamicTableEntity.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/DynamicTableEntity.cs deleted file mode 100644 index a7efde0a9cce4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/DynamicTableEntity.cs +++ /dev/null @@ -1,147 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - - /// - /// A type which allows callers direct access to the property map of the entity. This class eliminates the use of reflection for serialization and deserialization. - /// - public sealed class DynamicTableEntity : ITableEntity - { - /// - /// Initializes a new instance of the class. - /// - public DynamicTableEntity() - { - this.Properties = new Dictionary(); - } - - /// - /// Initializes a new instance of the class with the specified partition key and row key. - /// - /// The partition key value for the entity. - /// The row key value for the entity. - public DynamicTableEntity(string partitionKey, string rowKey) - : this(partitionKey, rowKey, DateTimeOffset.MinValue, null /* timestamp */, new Dictionary()) - { - } - - /// - /// Initializes a new instance of the class with the entity's partition key, row key, ETag (if available/required), and properties. - /// - /// The entity's partition key. - /// The entity's row key. - /// The entity's current ETag. - /// The entity's properties, indexed by property name. - public DynamicTableEntity(string partitionKey, string rowKey, string etag, IDictionary properties) - : this(partitionKey, rowKey, DateTimeOffset.MinValue, etag, properties) - { - } - - /// - /// Initializes a new instance of the class with the entity's partition key, row key, time stamp, ETag (if available/required), and properties. - /// - /// The entity's partition key. - /// The entity's row key. - /// The timestamp for this entity as returned by Windows Azure. - /// The entity's current ETag; set to null to ignore the ETag during subsequent update operations. - /// An containing a map of property names to data typed values to store in the new . - internal DynamicTableEntity(string partitionKey, string rowKey, DateTimeOffset timestamp, string etag, IDictionary properties) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowKey", rowKey); - CommonUtility.AssertNotNull("properties", properties); - - // Store the information about this entity. Make a copy of - // the properties list, in case the caller decides to reuse - // the list. - this.PartitionKey = partitionKey; - this.RowKey = rowKey; - this.Timestamp = timestamp; - this.ETag = etag; - - this.Properties = properties; - } - - /// - /// Gets or sets the properties in the table entity, indexed by property name. - /// - /// The entity properties. - public IDictionary Properties { get; set; } - - /// - /// Gets or sets the entity's partition key. - /// - /// The entity partition key. - public string PartitionKey { get; set; } - - /// - /// Gets or sets the entity's row key. - /// - /// The entity row key. - public string RowKey { get; set; } - - /// - /// Gets or sets the entity's timestamp. - /// - /// The entity timestamp. - public DateTimeOffset Timestamp { get; set; } - - /// - /// Gets or sets the entity's current ETag. Set this value to '*' to blindly overwrite an entity as part of an update operation. - /// - /// The entity ETag. - public string ETag { get; set; } - -#if !WINDOWS_RT - /// - /// Gets or sets the entity's property, given the name of the property. - /// - /// The name of the property. - /// The property. - public EntityProperty this[string key] - { - get { return this.Properties[key]; } - set { this.Properties[key] = value; } - } -#endif - - /// - /// Deserializes this instance using the specified of property names to values of type . - /// - /// A collection containing the of string property names mapped to values of type to store in this instance. - /// An object used to track the execution of the operation. - public void ReadEntity(IDictionary properties, OperationContext operationContext) - { - this.Properties = properties; - } - - /// - /// Serializes the of property names mapped to values of type from this instance. - /// - /// An object used to track the execution of the operation. - /// A collection containing the map of string property names to values of type stored in this instance. - public IDictionary WriteEntity(OperationContext operationContext) - { - return this.Properties; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EdmType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/EdmType.cs deleted file mode 100644 index 01bc4d65ac8aa..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EdmType.cs +++ /dev/null @@ -1,69 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Enumeration containing the types of values that can be stored in - /// a table entity property. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm", Justification = "Reviewed")] - public enum EdmType - { - /// - /// Represents fixed- or variable-length character data. - /// - String, - - /// - /// Represents fixed- or variable-length binary data. - /// - Binary, - - /// - /// Represents the mathematical concept of binary-valued logic. - /// - Boolean, - - /// - /// Represents date and time. - /// - DateTime, - - /// - /// Represents a floating point number with 15 digits precision that can represent values with approximate range of +/- 2.23e -308 through +/- 1.79e +308. - /// - Double, - - /// - /// Represents a 16-byte (128-bit) unique identifier value. - /// - Guid, - - /// - /// Represents a signed 32-bit integer value. - /// - Int32, - - /// - /// Represents a signed 64-bit integer value. - /// - Int64, - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityProperty.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityProperty.cs deleted file mode 100644 index 02ed909049830..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityProperty.cs +++ /dev/null @@ -1,800 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Linq; - -#if WINDOWS_RT - using System.Runtime.InteropServices.WindowsRuntime; -#endif - - /// - /// Class for storing information about a single property in an entity in a table. - /// - public sealed class EntityProperty - { - #region Value Storage - - private object propertyAsObject; - - /// - /// Gets the as a generic object. - /// - public object PropertyAsObject - { - get - { - return this.propertyAsObject; - } - - internal set - { - this.IsNull = value == null; - this.propertyAsObject = value; - } - } - - #endregion - - #region RT FactoryMethods - - /// - /// Creates a new object that represents the specified offset value. - /// - /// The value for the new . - /// A new of the offset type. - public static EntityProperty GeneratePropertyForDateTimeOffset(DateTimeOffset? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified byte array. - /// - /// The value for the new . - /// A new of the byte array. - public static EntityProperty GeneratePropertyForByteArray( -#if WINDOWS_RT - [ReadOnlyArray] -#endif -byte[] input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - public static EntityProperty GeneratePropertyForBool(bool? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - public static EntityProperty GeneratePropertyForDouble(double? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - public static EntityProperty GeneratePropertyForGuid(Guid? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ForInt", Justification = "Reviewed")] - public static EntityProperty GeneratePropertyForInt(int? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - public static EntityProperty GeneratePropertyForLong(long? input) - { - return new EntityProperty(input); - } - - /// - /// Creates a new object that represents the specified value. - /// - /// The value for the new . - /// A new of the type. - public static EntityProperty GeneratePropertyForString(string input) - { - return new EntityProperty(input); - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class by using the - /// byte array value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(byte[] input) - : this(EdmType.Binary) - { - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(bool? input) - : this(EdmType.Boolean) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(DateTimeOffset? input) - : this(EdmType.DateTime) - { - if (input.HasValue) - { - // Convert to datetime - this.PropertyAsObject = input.Value.UtcDateTime; - } - else - { - this.IsNull = true; - this.PropertyAsObject = new DateTime?(); - } - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(DateTime? input) - : this(EdmType.DateTime) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(double? input) - : this(EdmType.Double) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(Guid? input) - : this(EdmType.Guid) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(int? input) - : this(EdmType.Int32) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . -#if WINDOWS_RT - internal -#else - public -#endif - EntityProperty(long? input) - : this(EdmType.Int64) - { - this.IsNull = !input.HasValue; - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the class by using the - /// value of the property. - /// - /// The value for the new . - public EntityProperty(string input) - : this(EdmType.String) - { - this.PropertyAsObject = input; - } - - /// - /// Initializes a new instance of the EntityProperty class given the - /// EdmType of the property (the value must be set by a public - /// constructor). - /// - private EntityProperty(EdmType propertyType) - { - this.PropertyType = propertyType; - } - - #endregion - - /// - /// Gets the of this object. - /// - /// The of this object. - public EdmType PropertyType { get; private set; } - - #region Properties - - /// - /// Gets or sets the byte array value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than an byte array. - /// - /// The byte array value of this object. - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Reviewed.")] - public byte[] BinaryValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Binary); - } - - return (byte[])this.PropertyAsObject; - } - - set - { - if (value != null) - { - this.EnforceType(EdmType.Binary); - } - - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than an Object. - /// - /// The value of this object. - public bool? BooleanValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Boolean); - } - - return (bool?)this.PropertyAsObject; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.Boolean); - } - - this.PropertyAsObject = value; - } - } - - internal DateTime? DateTime - { - get - { - return (DateTime?)this.PropertyAsObject; - } - - set - { - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the offset value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than a object. - /// - /// The offset value of this object. - public DateTimeOffset? DateTimeOffsetValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.DateTime); - } - - return this.PropertyAsObject != null ? new DateTimeOffset((DateTime)this.PropertyAsObject) : (DateTimeOffset?)null; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.DateTime); - - // Convert to datetime - this.PropertyAsObject = value.Value.UtcDateTime; - } - else - { - this.PropertyAsObject = (DateTime?)null; - } - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than a object. - /// - /// The value of this object. - public double? DoubleValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Double); - } - - return (double?)this.PropertyAsObject; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.Double); - } - - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than a object. - /// - /// The value of this object. - public Guid? GuidValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Guid); - } - - return (Guid?)this.PropertyAsObject; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.Guid); - } - - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than an Object. - /// - /// The value of this object. - public int? Int32Value - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Int32); - } - - return (int?)this.PropertyAsObject; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.Int32); - } - - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than an Object. - /// - /// The value of this object. - public long? Int64Value - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.Int64); - } - - return (long?)this.PropertyAsObject; - } - - set - { - if (value.HasValue) - { - this.EnforceType(EdmType.Int64); - } - - this.PropertyAsObject = value; - } - } - - /// - /// Gets or sets the value of this object. - /// An exception will be thrown if you attempt to set this property to anything other than a object. - /// - /// The value of this object. - public string StringValue - { - get - { - if (!this.IsNull) - { - this.EnforceType(EdmType.String); - } - - return (string)this.PropertyAsObject; - } - - set - { - if (value != null) - { - this.EnforceType(EdmType.String); - } - - this.PropertyAsObject = value; - } - } - - #endregion - - /// - /// Compares the given object (which is probably an ) - /// for equality with this object. - /// - /// The other object. - /// true if the objects are equivalent; false otherwise. - public override bool Equals(object obj) - { - EntityProperty other = obj as EntityProperty; - if (other == null) - { - return false; - } - - if (this.IsNull) - { - return other.IsNull && other.PropertyType == this.PropertyType; - } - - switch (this.PropertyType) - { - case EdmType.Binary: - return this.BinaryValue.Length == other.BinaryValue.Length - && this.BinaryValue.SequenceEqual(other.BinaryValue); - case EdmType.Boolean: - return this.BooleanValue == other.BooleanValue; - case EdmType.DateTime: - return this.DateTime == other.DateTime; - case EdmType.Double: - return this.DoubleValue == other.DoubleValue; - case EdmType.Guid: - return this.GuidValue == other.GuidValue; - case EdmType.Int32: - return this.Int32Value == other.Int32Value; - case EdmType.Int64: - return this.Int64Value == other.Int64Value; - case EdmType.String: - return string.Equals(this.StringValue, other.StringValue); - default: - return this.PropertyAsObject == other.PropertyAsObject; - } - } - - /// - /// Gets the hash code for this entity property. - /// - /// The hash code for the entity property. - public override int GetHashCode() - { - return this.PropertyAsObject.GetHashCode(); - } - - internal bool IsNull { get; set; } - - /// - /// Creates an from the object. - /// - /// The value of the object. - /// The reference to the object created. - public static EntityProperty CreateEntityPropertyFromObject(object entityValue) - { - return CreateEntityPropertyFromObject(entityValue, true); - } - - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code clarity.")] - internal static EntityProperty CreateEntityPropertyFromObject(object value, bool allowUnknownTypes) - { - if (value is string) - { - return new EntityProperty((string)value); - } - else if (value is byte[]) - { - return new EntityProperty((byte[])value); - } - else if (value is bool) - { - return new EntityProperty((bool)value); - } - else if (value is bool?) - { - return new EntityProperty((bool?)value); - } - else if (value is DateTime) - { - return new EntityProperty((DateTime)value); - } - else if (value is DateTime?) - { - return new EntityProperty((DateTime?)value); - } - else if (value is DateTimeOffset) - { - return new EntityProperty((DateTimeOffset)value); - } - else if (value is DateTimeOffset?) - { - return new EntityProperty((DateTimeOffset?)value); - } - else if (value is double) - { - return new EntityProperty((double)value); - } - else if (value is double?) - { - return new EntityProperty((double?)value); - } - else if (value is Guid?) - { - return new EntityProperty((Guid?)value); - } - else if (value is Guid) - { - return new EntityProperty((Guid)value); - } - else if (value is int) - { - return new EntityProperty((int)value); - } - else if (value is int?) - { - return new EntityProperty((int?)value); - } - else if (value is long) - { - return new EntityProperty((long)value); - } - else if (value is long?) - { - return new EntityProperty((long?)value); - } - else if (value == null) - { - return new EntityProperty((string)null); - } - else if (allowUnknownTypes) - { - return new EntityProperty(value.ToString()); - } - else - { - return null; - } - } - - internal static EntityProperty CreateEntityPropertyFromObject(object value, Type type) - { - if (type == typeof(string)) - { - return new EntityProperty((string)value); - } - else if (type == typeof(byte[])) - { - return new EntityProperty((byte[])value); - } - else if (type == typeof(bool)) - { - return new EntityProperty((bool)value); - } - else if (type == typeof(bool?)) - { - return new EntityProperty((bool?)value); - } - else if (type == typeof(DateTime)) - { - return new EntityProperty((DateTime)value); - } - else if (type == typeof(DateTime?)) - { - return new EntityProperty((DateTime?)value); - } - else if (type == typeof(DateTimeOffset)) - { - return new EntityProperty((DateTimeOffset)value); - } - else if (type == typeof(DateTimeOffset?)) - { - return new EntityProperty((DateTimeOffset?)value); - } - else if (type == typeof(double)) - { - return new EntityProperty((double)value); - } - else if (type == typeof(double?)) - { - return new EntityProperty((double?)value); - } - else if (type == typeof(Guid?)) - { - return new EntityProperty((Guid?)value); - } - else if (type == typeof(Guid)) - { - return new EntityProperty((Guid)value); - } - else if (type == typeof(int)) - { - return new EntityProperty((int)value); - } - else if (type == typeof(int?)) - { - return new EntityProperty((int?)value); - } - else if (type == typeof(long)) - { - return new EntityProperty((long)value); - } - else if (type == typeof(long?)) - { - return new EntityProperty((long?)value); - } - else - { - return null; - } - } - - /// - /// Ensures that the given type matches the type of this entity - /// property; throws an exception if the types do not match. - /// - private void EnforceType(EdmType requestedType) - { - if (this.PropertyType != requestedType) - { - throw new InvalidOperationException(string.Format( - CultureInfo.InvariantCulture, - "Cannot return {0} type for a {1} typed property.", - requestedType, - this.PropertyType)); - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityReadFlags.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityReadFlags.cs deleted file mode 100644 index 4f90916c42f85..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityReadFlags.cs +++ /dev/null @@ -1,32 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - - [Flags] - internal enum EntityReadFlags - { - PartitionKey = 0x01, - RowKey = 0x02, - Timestamp = 0x04, - Etag = 0x08, - Properties = 0x10, - All = 0x1f - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityResolver.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityResolver.cs deleted file mode 100644 index d6d5d6ab54d41..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityResolver.cs +++ /dev/null @@ -1,38 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - -#if !WINDOWS_RTMD - /// - /// Returns a delegate for resolving entities. - /// - /// The type into which the query results are projected. - /// The partition key. - /// The row key. - /// The timestamp. - /// A dictionary of properties. - /// The ETag. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "etag", Justification = "Reviewed: etag can be used for identifier names.")] - public delegate T EntityResolver(string partitionKey, string rowKey, DateTimeOffset timestamp, IDictionary properties, string etag); -#endif -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityUtilities.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityUtilities.cs deleted file mode 100644 index 9d0b4e7add382..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/EntityUtilities.cs +++ /dev/null @@ -1,113 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - using System.Collections.Concurrent; - using System.Linq.Expressions; - using System.Reflection; - using EntityActivator = System.Func; - using Microsoft.WindowsAzure.Storage.Core; -#endif - - internal static class EntityUtilities - { - internal static TElement ResolveEntityByType(string partitionKey, string rowKey, DateTimeOffset timestamp, IDictionary properties, string etag) - { - ITableEntity entity = (ITableEntity)InstantiateEntityFromType(typeof(TElement)); - - entity.PartitionKey = partitionKey; - entity.RowKey = rowKey; - entity.Timestamp = timestamp; - entity.ReadEntity(properties, null); - entity.ETag = etag; - - return (TElement)entity; - } - - internal static DynamicTableEntity ResolveDynamicEntity(string partitionKey, string rowKey, DateTimeOffset timestamp, IDictionary properties, string etag) - { - DynamicTableEntity entity = new DynamicTableEntity(partitionKey, rowKey); - entity.Timestamp = timestamp; - entity.ReadEntity(properties, null); - entity.ETag = etag; - - return entity; - } - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - internal static object InstantiateEntityFromType(Type type) - { - EntityActivator activator = compiledActivators.GetOrAdd(type, GenerateActivator); - return activator(null /* no params */); - } -#else - internal static object InstantiateEntityFromType(Type type) - { - return Activator.CreateInstance(type); - } -#endif - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - private static EntityActivator GenerateActivator(Type type) - { - // Generate activator for parameterless constructor - return GenerateActivator(type, System.Type.EmptyTypes); - } - - private static EntityActivator GenerateActivator(Type type, Type[] ctorParamTypes) - { - ConstructorInfo constructorInfo = type.GetConstructor(ctorParamTypes); - if (constructorInfo == null) - { - throw new InvalidOperationException(SR.TableQueryTypeMustHaveDefaultParameterlessCtor); - } - - ParameterInfo[] parameterInfos = constructorInfo.GetParameters(); - - // Create a single param of type object[] - ParameterExpression parameterExpression = Expression.Parameter(typeof(object[]), "args"); - Expression[] argsExp = new Expression[parameterInfos.Length]; - - // Pick each arg from the params array and create a typed expression of them - for (int i = 0; i < parameterInfos.Length; i++) - { - Expression index = Expression.Constant(i); - Type paramType = parameterInfos[i].ParameterType; - Expression paramAccessorExp = Expression.ArrayIndex(parameterExpression, index); - Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); - argsExp[i] = paramCastExp; - } - - // Make a NewExpression that calls the ctor with the args we just created - NewExpression newExpression = Expression.New(constructorInfo, argsExp); - - // Create a lambda with the New Expression as body and our param object[] as arg - LambdaExpression lambda = Expression.Lambda(typeof(EntityActivator), newExpression, parameterExpression); - - // Compile it - return (EntityActivator)lambda.Compile(); - } - - // Per http://blogs.msdn.com/b/pfxteam/archive/2011/11/08/10235147.aspx not specifying default concurrency to allow for dynamic lock allocation based on size - private static ConcurrentDictionary compiledActivators = new ConcurrentDictionary(); -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/ITableEntity.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/ITableEntity.cs deleted file mode 100644 index 8b2900c720e28..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/ITableEntity.cs +++ /dev/null @@ -1,77 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - - /// - /// An interface required for table entity types. The interface declares getter and setter methods for the mandatory entity properties, and - /// and methods for serialization and de-serialization of all entity properties using a property dictionary. Create classes implementing to customize property - /// storage, retrieval, serialization and de-serialization, and to provide additional custom logic for a table entity. - /// - /// The storage client library includes two implementations of that provide for simple property access and serialization: - /// implements and provides a simple property dictionary to store and retrieve properties. Use a for simple access - /// to entity properties when only a subset of properties are returned (for example, by a select clause in a query), or for scenarios where your query can return multiple entity types - /// with different properties. You can also use this type to perform bulk table updates of heterogeneous entities without losing property information. - /// is an implementation of that uses reflection-based serialization and de-serialization behavior in its and methods. - /// -derived classes with methods that follow a convention for types and naming are serialized and deserialized automatically. -derived classes must also provide a get-able and set-able public - /// property of a type that is supported by the Windows Azure Table service. - public interface ITableEntity - { - /// - /// Gets or sets the entity's partition key. - /// - /// The entity's partition key. - string PartitionKey { get; set; } - - /// - /// Gets or sets the entity's row key. - /// - /// The entity's row key. - string RowKey { get; set; } - - /// - /// Gets or sets the entity's time stamp. - /// - /// The entity's time stamp. The property is populated by the Windows Azure Table Service. - DateTimeOffset Timestamp { get; set; } - - /// - /// Gets or sets the entity's current ETag. Set this value to '*' - /// in order to blindly overwrite an entity as part of an update - /// operation. - /// - /// The entity's time stamp. - string ETag { get; set; } - - /// - /// Populates the entity's properties from the data values in the dictionary. - /// - /// The dictionary of string property names to data values to deserialize and store in this table entity instance. - /// An object used to track the execution of the operation. - void ReadEntity(IDictionary properties, OperationContext operationContext); - - /// - /// Serializes the of property names mapped to data values from the entity instance. - /// - /// An object used to track the execution of the operation. - /// A dictionary of property names to data typed values created by serializing this table entity instance. - IDictionary WriteEntity(OperationContext operationContext); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableAccessPolicyResponse.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableAccessPolicyResponse.cs deleted file mode 100644 index c1dd1f69ce0da..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableAccessPolicyResponse.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.IO; - using System.Xml.Linq; - - /// - /// Parses the response XML from an operation to set the access policy for a table. - /// - internal class TableAccessPolicyResponse : AccessPolicyResponseBase - { - /// - /// Initializes a new instance of the TableAccessPolicyResponse class. - /// - /// The stream to be parsed. - internal TableAccessPolicyResponse(Stream stream) - : base(stream) - { - } - - /// - /// Parses the current element. - /// - /// The shared access policy element to parse. - /// The shared access policy. - protected override SharedAccessTablePolicy ParseElement(XElement accessPolicyElement) - { - CommonUtility.AssertNotNull("accessPolicyElement", accessPolicyElement); - - SharedAccessTablePolicy accessPolicy = new SharedAccessTablePolicy(); - string sharedAccessStartTimeString = (string)accessPolicyElement.Element(Constants.Start); - if (!string.IsNullOrEmpty(sharedAccessStartTimeString)) - { - accessPolicy.SharedAccessStartTime = Uri.UnescapeDataString(sharedAccessStartTimeString).ToUTCTime(); - } - - string sharedAccessExpiryTimeString = (string)accessPolicyElement.Element(Constants.Expiry); - if (!string.IsNullOrEmpty(sharedAccessExpiryTimeString)) - { - accessPolicy.SharedAccessExpiryTime = Uri.UnescapeDataString(sharedAccessExpiryTimeString).ToUTCTime(); - } - - string permissionsString = (string)accessPolicyElement.Element(Constants.Permission); - if (!string.IsNullOrEmpty(permissionsString)) - { - accessPolicy.Permissions = SharedAccessTablePolicy.PermissionsFromString(permissionsString); - } - - return accessPolicy; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableConstants.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableConstants.cs deleted file mode 100644 index 2b1475d151fc5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableConstants.cs +++ /dev/null @@ -1,123 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - - /// - /// A set of constants used in operations against the Table service. - /// -#if WINDOWS_DESKTOP - public -#else - internal -#endif - static class TableConstants - { - /// - /// Stores the header prefix for continuation information. - /// - public const string TableServicePrefixForTableContinuation = "x-ms-continuation-"; - - /// - /// Stores the header suffix for the next partition key. - /// - public const string TableServiceNextPartitionKey = "NextPartitionKey"; - - /// - /// Stores the header suffix for the next row key. - /// - public const string TableServiceNextRowKey = "NextRowKey"; - - /// - /// Stores the table suffix for the next table name. - /// - public const string TableServiceNextTableName = "NextTableName"; - - /// - /// Stores the maximum results the table service can return. - /// - public const int TableServiceMaxResults = 1000; - - /// - /// The maximum size of a string property for the table service in bytes. - /// - public const int TableServiceMaxStringPropertySizeInBytes = 64 * 1024; - - /// - /// The maximum size of a string property for the table service in bytes. - /// - public const long TableServiceMaxPayload = 20 * Constants.MB; - - /// - /// The maximum size of a string property for the table service in chars. - /// - public const int TableServiceMaxStringPropertySizeInChars = TableServiceMaxStringPropertySizeInBytes / 2; - - /// - /// The name of the special table used to store tables. - /// - public const string TableServiceTablesName = "Tables"; - - /// - /// The name of the partition key property. - /// - public const string PartitionKey = "PartitionKey"; - - /// - /// The name of the row key property. - /// - public const string RowKey = "RowKey"; - - /// - /// The name of the Timestamp property. - /// - public const string Timestamp = "Timestamp"; - - /// - /// The name of the ETag property. - /// - public const string Etag = "ETag"; - - /// - /// The name of the property that stores the table name. - /// - public const string TableName = "TableName"; - - /// - /// The query filter clause name. - /// - public const string Filter = "$filter"; - - /// - /// The query top clause name. - /// - public const string Top = "$top"; - - /// - /// The query select clause name. - /// - public const string Select = "$select"; - - /// - /// The minimum DateTime supported. - /// - public static readonly DateTimeOffset MinDateTime = new DateTimeOffset(1601, 1, 1, 0, 0, 0, TimeSpan.Zero); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableErrorCodeStrings.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableErrorCodeStrings.cs deleted file mode 100644 index c21fe9f5d93ed..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableErrorCodeStrings.cs +++ /dev/null @@ -1,175 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - /// - /// Provides error code strings that are specific to the Windows Azure Table service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class TableErrorCodeStrings - { - /// - /// The request uses X-HTTP-Method with an HTTP verb other than POST. - /// - public const string XMethodNotUsingPost = "XMethodNotUsingPost"; - - /// - /// The specified X-HTTP-Method is invalid. - /// - public const string XMethodIncorrectValue = "XMethodIncorrectValue"; - - /// - /// More than one X-HTTP-Method is specified. - /// - public const string XMethodIncorrectCount = "XMethodIncorrectCount"; - - /// - /// The specified table has no properties. - /// - public const string TableHasNoProperties = "TableHasNoProperties"; - - /// - /// A property is specified more than once. - /// - public const string DuplicatePropertiesSpecified = "DuplicatePropertiesSpecified"; - - /// - /// The specified table has no such property. - /// - public const string TableHasNoSuchProperty = "TableHasNoSuchProperty"; - - /// - /// A duplicate key property was specified. - /// - public const string DuplicateKeyPropertySpecified = "DuplicateKeyPropertySpecified"; - - /// - /// The specified table already exists. - /// - public const string TableAlreadyExists = "TableAlreadyExists"; - - /// - /// The specified table was not found. - /// - public const string TableNotFound = "TableNotFound"; - - /// - /// The specified entity was not found. - /// - public const string EntityNotFound = "EntityNotFound"; - - /// - /// The specified entity already exists. - /// - public const string EntityAlreadyExists = "EntityAlreadyExists"; - - /// - /// The partition key was not specified. - /// - public const string PartitionKeyNotSpecified = "PartitionKeyNotSpecified"; - - /// - /// One or more specified operators are invalid. - /// - public const string OperatorInvalid = "OperatorInvalid"; - - /// - /// The specified update condition was not satisfied. - /// - public const string UpdateConditionNotSatisfied = "UpdateConditionNotSatisfied"; - - /// - /// All properties must have values. - /// - public const string PropertiesNeedValue = "PropertiesNeedValue"; - - /// - /// The partition key property cannot be updated. - /// - public const string PartitionKeyPropertyCannotBeUpdated = "PartitionKeyPropertyCannotBeUpdated"; - - /// - /// The entity contains more properties than allowed. - /// - public const string TooManyProperties = "TooManyProperties"; - - /// - /// The entity is larger than the maximum size permitted. - /// - public const string EntityTooLarge = "EntityTooLarge"; - - /// - /// The property value is larger than the maximum size permitted. - /// - public const string PropertyValueTooLarge = "PropertyValueTooLarge"; - - /// - /// One or more value types are invalid. - /// - public const string InvalidValueType = "InvalidValueType"; - - /// - /// The specified table is being deleted. - /// - public const string TableBeingDeleted = "TableBeingDeleted"; - - /// - /// The Table service server is out of memory. - /// - public const string TableServerOutOfMemory = "TableServerOutOfMemory"; - - /// - /// The type of the primary key property is invalid. - /// - public const string PrimaryKeyPropertyIsInvalidType = "PrimaryKeyPropertyIsInvalidType"; - - /// - /// The property name exceeds the maximum allowed length. - /// - public const string PropertyNameTooLong = "PropertyNameTooLong"; - - /// - /// The property name is invalid. - /// - public const string PropertyNameInvalid = "PropertyNameInvalid"; - - /// - /// Batch operations are not supported for this operation type. - /// - public const string BatchOperationNotSupported = "BatchOperationNotSupported"; - - /// - /// JSON format is not supported. - /// - public const string JsonFormatNotSupported = "JsonFormatNotSupported"; - - /// - /// The specified method is not allowed. - /// - public const string MethodNotAllowed = "MethodNotAllowed"; - - /// - /// The specified operation is not yet implemented. - /// - public const string NotImplemented = "NotImplemented"; - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableRequest.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableRequest.cs deleted file mode 100644 index b013f9b01c045..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Protocol/TableRequest.cs +++ /dev/null @@ -1,73 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.IO; - - /// - /// Provides a set of helper methods for constructing a request against the Table service. - /// -#if WINDOWS_RT - internal -#else - public -#endif - static class TableRequest - { - /// - /// Writes a collection of shared access policies to the specified stream in XML format. - /// - /// A collection of shared access policies. - /// An output stream. - public static void WriteSharedAccessIdentifiers(SharedAccessTablePolicies sharedAccessPolicies, Stream outputStream) - { - Request.WriteSharedAccessIdentifiers( - sharedAccessPolicies, - outputStream, - (policy, writer) => - { - writer.WriteElementString( - Constants.Start, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessStartTime)); - writer.WriteElementString( - Constants.Expiry, - SharedAccessSignatureHelper.GetDateTimeOrEmpty(policy.SharedAccessExpiryTime)); - writer.WriteElementString( - Constants.Permission, - SharedAccessTablePolicy.PermissionsToString(policy.Permissions)); - }); - } - - internal static string ExtractEntityIndexFromExtendedErrorInformation(RequestResult result) - { - if (result != null && result.ExtendedErrorInformation != null && !string.IsNullOrEmpty(result.ExtendedErrorInformation.ErrorMessage)) - { - int semiDex = result.ExtendedErrorInformation.ErrorMessage.IndexOf(":"); - - if (semiDex > 0 && semiDex < 3) - { - return result.ExtendedErrorInformation.ErrorMessage.Substring(0, semiDex); - } - } - - return null; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/QueryComparisons.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/QueryComparisons.cs deleted file mode 100644 index d167538964716..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/QueryComparisons.cs +++ /dev/null @@ -1,98 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Defines the set of comparison operators that may be used for constructing queries. - /// - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Due to Javascript projection limitations.")] - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1303:ConstFieldNamesMustBeginWithUpperCaseLetter", Justification = "Due to Javascript projection limitations..")] - public static class QueryComparisons - { -#if WINDOWS_RT - internal const string equal = "eq"; - internal const string notEqual = "ne"; - internal const string greaterThan = "gt"; - internal const string greaterThanOrEqual = "ge"; - internal const string lessThan = "lt"; - internal const string lessThanOrEqual = "le"; - - public static string Equal - { - get { return equal; } - } - - public static string NotEqual - { - get { return notEqual; } - } - - public static string GreaterThan - { - get { return greaterThan; } - } - - public static string GreaterThanOrEqual - { - get { return greaterThanOrEqual; } - } - - public static string LessThan - { - get { return lessThan; } - } - - public static string LessThanOrEqual - { - get { return lessThanOrEqual; } - } -#else - /// - /// Represents the Equal operator. - /// - public const string Equal = "eq"; - - /// - /// Represents the Not Equal operator. - /// - public const string NotEqual = "ne"; - - /// - /// Represents the Greater Than operator. - /// - public const string GreaterThan = "gt"; - - /// - /// Represents the Greater Than or Equal operator. - /// - public const string GreaterThanOrEqual = "ge"; - - /// - /// Represents the Less Than operator. - /// - public const string LessThan = "lt"; - - /// - /// Represents the Less Than or Equal operator. - /// - public const string LessThanOrEqual = "le"; -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ALinqExpressionVisitor.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ALinqExpressionVisitor.cs deleted file mode 100644 index 754761a20760d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ALinqExpressionVisitor.cs +++ /dev/null @@ -1,489 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Globalization; - using System.Linq.Expressions; -#if ASTORIA_LIGHT - using System.Reflection; - using System.Security; - using System.Security.Permissions; - - internal static class ExpressionHelpers - { - private static MethodInfo lambdaFunc; - - internal static LambdaExpression CreateLambda(Expression body, params ParameterExpression[] parameters) - { - return CreateLambda(InferDelegateType(body, parameters), body, parameters); - } - - internal static LambdaExpression CreateLambda(Type delegateType, Expression body, params ParameterExpression[] parameters) - { - var args = new[] { Expression.Parameter(typeof(Expression), "body"), Expression.Parameter(typeof(ParameterExpression[]), "parameters") }; - - var lambdaFactory = Expression.Lambda>( - Expression.Call(GetLambdaFactoryMethod(delegateType), args), args - ); - - return lambdaFactory.Compile().Invoke(body, parameters); - } - - private static Type InferDelegateType(Expression body, params ParameterExpression[] parameters) - { - bool isVoid = body.Type == typeof(void); - int length = (parameters == null) ? 0 : parameters.Length; - - var typeArgs = new Type[length + (isVoid ? 0 : 1)]; - for (int i = 0; i < length; i++) - { - typeArgs[i] = parameters[i].Type; - } - if (isVoid) - { - return Expression.GetActionType(typeArgs); - } - else - { - typeArgs[length] = body.Type; - return Expression.GetFuncType(typeArgs); - } - } - - private static MethodInfo GetLambdaFactoryMethod(Type delegateType) - { - if (lambdaFunc == null) - { - lambdaFunc = new Func>(Expression.Lambda).Method.GetGenericMethodDefinition(); - } - - return lambdaFunc.MakeGenericMethod(delegateType); - } - } -#endif - - internal abstract class ALinqExpressionVisitor - { - internal virtual Expression Visit(Expression exp) - { - if (exp == null) - { - return exp; - } - - switch (exp.NodeType) - { - case ExpressionType.UnaryPlus: - case ExpressionType.Negate: - case ExpressionType.NegateChecked: - case ExpressionType.Not: - case ExpressionType.Convert: - case ExpressionType.ConvertChecked: - case ExpressionType.ArrayLength: - case ExpressionType.Quote: - case ExpressionType.TypeAs: - return this.VisitUnary((UnaryExpression)exp); - case ExpressionType.Add: - case ExpressionType.AddChecked: - case ExpressionType.Subtract: - case ExpressionType.SubtractChecked: - case ExpressionType.Multiply: - case ExpressionType.MultiplyChecked: - case ExpressionType.Divide: - case ExpressionType.Modulo: -#if !ASTORIA_CLIENT - case ExpressionType.Power: -#endif - case ExpressionType.And: - case ExpressionType.AndAlso: - case ExpressionType.Or: - case ExpressionType.OrElse: - case ExpressionType.LessThan: - case ExpressionType.LessThanOrEqual: - case ExpressionType.GreaterThan: - case ExpressionType.GreaterThanOrEqual: - case ExpressionType.Equal: - case ExpressionType.NotEqual: - case ExpressionType.Coalesce: - case ExpressionType.ArrayIndex: - case ExpressionType.RightShift: - case ExpressionType.LeftShift: - case ExpressionType.ExclusiveOr: - return this.VisitBinary((BinaryExpression)exp); - case ExpressionType.TypeIs: - return this.VisitTypeIs((TypeBinaryExpression)exp); - case ExpressionType.Conditional: - return this.VisitConditional((ConditionalExpression)exp); - case ExpressionType.Constant: - return this.VisitConstant((ConstantExpression)exp); - case ExpressionType.Parameter: - return this.VisitParameter((ParameterExpression)exp); - case ExpressionType.MemberAccess: - return this.VisitMemberAccess((MemberExpression)exp); - case ExpressionType.Call: - return this.VisitMethodCall((MethodCallExpression)exp); - case ExpressionType.Lambda: - return this.VisitLambda((LambdaExpression)exp); - case ExpressionType.New: - return this.VisitNew((NewExpression)exp); - case ExpressionType.NewArrayInit: - case ExpressionType.NewArrayBounds: - return this.VisitNewArray((NewArrayExpression)exp); - case ExpressionType.Invoke: - return this.VisitInvocation((InvocationExpression)exp); - case ExpressionType.MemberInit: - return this.VisitMemberInit((MemberInitExpression)exp); - case ExpressionType.ListInit: - return this.VisitListInit((ListInitExpression)exp); - default: - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqUnsupportedExpression, exp.NodeType.ToString())); - } - } - - internal virtual MemberBinding VisitBinding(MemberBinding binding) - { - switch (binding.BindingType) - { - case MemberBindingType.Assignment: - return this.VisitMemberAssignment((MemberAssignment)binding); - case MemberBindingType.MemberBinding: - return this.VisitMemberMemberBinding((MemberMemberBinding)binding); - case MemberBindingType.ListBinding: - return this.VisitMemberListBinding((MemberListBinding)binding); - default: - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqUnsupportedExpression, binding.BindingType.ToString())); - } - } - - internal virtual ElementInit VisitElementInitializer(ElementInit initializer) - { - ReadOnlyCollection arguments = this.VisitExpressionList(initializer.Arguments); - if (arguments != initializer.Arguments) - { - return Expression.ElementInit(initializer.AddMethod, arguments); - } - - return initializer; - } - - internal virtual Expression VisitUnary(UnaryExpression u) - { - Expression operand = this.Visit(u.Operand); - if (operand != u.Operand) - { - return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method); - } - - return u; - } - - internal virtual Expression VisitBinary(BinaryExpression b) - { - Expression left = this.Visit(b.Left); - Expression right = this.Visit(b.Right); - Expression conversion = this.Visit(b.Conversion); - if (left != b.Left || right != b.Right || conversion != b.Conversion) - { - if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null) - { - return Expression.Coalesce(left, right, conversion as LambdaExpression); - } - else - { - return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method); - } - } - - return b; - } - - internal virtual Expression VisitTypeIs(TypeBinaryExpression b) - { - Expression expr = this.Visit(b.Expression); - if (expr != b.Expression) - { - return Expression.TypeIs(expr, b.TypeOperand); - } - - return b; - } - - internal virtual Expression VisitConstant(ConstantExpression c) - { - return c; - } - - internal virtual Expression VisitConditional(ConditionalExpression c) - { - Expression test = this.Visit(c.Test); - Expression iftrue = this.Visit(c.IfTrue); - Expression iffalse = this.Visit(c.IfFalse); - if (test != c.Test || iftrue != c.IfTrue || iffalse != c.IfFalse) - { - return Expression.Condition(test, iftrue, iffalse); - } - - return c; - } - - internal virtual Expression VisitParameter(ParameterExpression p) - { - return p; - } - - internal virtual Expression VisitMemberAccess(MemberExpression m) - { - Expression exp = this.Visit(m.Expression); - if (exp != m.Expression) - { - return Expression.MakeMemberAccess(exp, m.Member); - } - - return m; - } - - internal virtual Expression VisitMethodCall(MethodCallExpression m) - { - Expression obj = this.Visit(m.Object); - - IEnumerable args = this.VisitExpressionList(m.Arguments); - if (obj != m.Object || args != m.Arguments) - { - return Expression.Call(obj, m.Method, args); - } - - return m; - } - - internal virtual ReadOnlyCollection VisitExpressionList(ReadOnlyCollection original) - { - List list = null; - for (int i = 0, n = original.Count; i < n; i++) - { - Expression p = this.Visit(original[i]); - if (list != null) - { - list.Add(p); - } - else if (p != original[i]) - { - list = new List(n); - for (int j = 0; j < i; j++) - { - list.Add(original[j]); - } - - list.Add(p); - } - } - - if (list != null) - { - return new ReadOnlyCollection(list); - } - - return original; - } - - internal virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment) - { - Expression e = this.Visit(assignment.Expression); - if (e != assignment.Expression) - { - return Expression.Bind(assignment.Member, e); - } - - return assignment; - } - - internal virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding) - { - IEnumerable bindings = this.VisitBindingList(binding.Bindings); - if (bindings != binding.Bindings) - { - return Expression.MemberBind(binding.Member, bindings); - } - - return binding; - } - - internal virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding) - { - IEnumerable initializers = this.VisitElementInitializerList(binding.Initializers); - if (initializers != binding.Initializers) - { - return Expression.ListBind(binding.Member, initializers); - } - - return binding; - } - - internal virtual IEnumerable VisitBindingList(ReadOnlyCollection original) - { - List list = null; - for (int i = 0, n = original.Count; i < n; i++) - { - MemberBinding b = this.VisitBinding(original[i]); - if (list != null) - { - list.Add(b); - } - else if (b != original[i]) - { - list = new List(n); - for (int j = 0; j < i; j++) - { - list.Add(original[j]); - } - - list.Add(b); - } - } - - if (list != null) - { - return list; - } - - return original; - } - - internal virtual IEnumerable VisitElementInitializerList(ReadOnlyCollection original) - { - List list = null; - for (int i = 0, n = original.Count; i < n; i++) - { - ElementInit init = this.VisitElementInitializer(original[i]); - if (list != null) - { - list.Add(init); - } - else if (init != original[i]) - { - list = new List(n); - for (int j = 0; j < i; j++) - { - list.Add(original[j]); - } - - list.Add(init); - } - } - - if (list != null) - { - return list; - } - - return original; - } - - internal virtual Expression VisitLambda(LambdaExpression lambda) - { - Expression body = this.Visit(lambda.Body); - if (body != lambda.Body) - { -#if !ASTORIA_LIGHT - return Expression.Lambda(lambda.Type, body, lambda.Parameters); -#else - ParameterExpression[] parameters = new ParameterExpression[lambda.Parameters.Count]; - lambda.Parameters.CopyTo(parameters, 0); - return ExpressionHelpers.CreateLambda(lambda.Type, body, parameters); -#endif - } - - return lambda; - } - - internal virtual NewExpression VisitNew(NewExpression nex) - { - IEnumerable args = this.VisitExpressionList(nex.Arguments); - if (args != nex.Arguments) - { - if (nex.Members != null) - { - return Expression.New(nex.Constructor, args, nex.Members); - } - else - { - return Expression.New(nex.Constructor, args); - } - } - - return nex; - } - - internal virtual Expression VisitMemberInit(MemberInitExpression init) - { - NewExpression n = this.VisitNew(init.NewExpression); - IEnumerable bindings = this.VisitBindingList(init.Bindings); - if (n != init.NewExpression || bindings != init.Bindings) - { - return Expression.MemberInit(n, bindings); - } - - return init; - } - - internal virtual Expression VisitListInit(ListInitExpression init) - { - NewExpression n = this.VisitNew(init.NewExpression); - IEnumerable initializers = this.VisitElementInitializerList(init.Initializers); - if (n != init.NewExpression || initializers != init.Initializers) - { - return Expression.ListInit(n, initializers); - } - - return init; - } - - internal virtual Expression VisitNewArray(NewArrayExpression na) - { - IEnumerable exprs = this.VisitExpressionList(na.Expressions); - if (exprs != na.Expressions) - { - if (na.NodeType == ExpressionType.NewArrayInit) - { - return Expression.NewArrayInit(na.Type.GetElementType(), exprs); - } - else - { - return Expression.NewArrayBounds(na.Type.GetElementType(), exprs); - } - } - - return na; - } - - internal virtual Expression VisitInvocation(InvocationExpression iv) - { - IEnumerable args = this.VisitExpressionList(iv.Arguments); - Expression expr = this.Visit(iv.Expression); - if (args != iv.Arguments || expr != iv.Expression) - { - return Expression.Invoke(expr, args); - } - - return iv; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ClientConvert.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ClientConvert.cs deleted file mode 100644 index 171f2d2722511..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ClientConvert.cs +++ /dev/null @@ -1,487 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Xml; - - #endregion Namespaces. - internal static class FXAssembly - { - internal const string Version = "4.0.0.0"; - } - - internal static class AssemblyRef - { - internal const string MicrosoftPublicKeyToken = "b03f5f7f11d50a3a"; - - internal const string EcmaPublicKeyToken = "b77a5c561934e089"; - } - - internal static class ClientConvert - { -#if !ASTORIA_LIGHT - private const string SystemDataLinq = "System.Data.Linq, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken; -#endif - - private static readonly Type[] KnownTypes = CreateKnownPrimitives(); - - private static readonly Dictionary NamedTypesMap = CreateKnownNamesMap(); - -#if !ASTORIA_LIGHT - private static bool needSystemDataLinqBinary = true; -#endif - - internal enum StorageType - { - Boolean, - - Byte, - - ByteArray, - - Char, - - CharArray, - - DateTime, - - DateTimeOffset, - - Decimal, - - Double, - - Guid, - - Int16, - - Int32, - - Int64, - - Single, - - String, - - SByte, - - TimeSpan, - - Type, - - UInt16, - - UInt32, - - UInt64, - - Uri, - - XDocument, - - XElement, - -#if !ASTORIA_LIGHT - Binary, -#endif - } - - internal static object ChangeType(string propertyValue, Type propertyType) - { - // Debug.Assert(null != propertyValue, "should never be passed null"); - try - { - switch ((StorageType)IndexOfStorage(propertyType)) - { - case StorageType.Boolean: - return XmlConvert.ToBoolean(propertyValue); - case StorageType.Byte: - return XmlConvert.ToByte(propertyValue); - case StorageType.ByteArray: - return Convert.FromBase64String(propertyValue); - case StorageType.Char: - return XmlConvert.ToChar(propertyValue); - case StorageType.CharArray: - return propertyValue.ToCharArray(); - case StorageType.DateTime: - return XmlConvert.ToDateTime(propertyValue, XmlDateTimeSerializationMode.RoundtripKind); - case StorageType.DateTimeOffset: - return XmlConvert.ToDateTimeOffset(propertyValue); - case StorageType.Decimal: - return XmlConvert.ToDecimal(propertyValue); - case StorageType.Double: - return XmlConvert.ToDouble(propertyValue); - case StorageType.Guid: - return new Guid(propertyValue); - case StorageType.Int16: - return XmlConvert.ToInt16(propertyValue); - case StorageType.Int32: - return XmlConvert.ToInt32(propertyValue); - case StorageType.Int64: - return XmlConvert.ToInt64(propertyValue); - case StorageType.Single: - return XmlConvert.ToSingle(propertyValue); - case StorageType.String: - return propertyValue; - case StorageType.SByte: - return XmlConvert.ToSByte(propertyValue); - case StorageType.TimeSpan: - return XmlConvert.ToTimeSpan(propertyValue); - case StorageType.Type: - return Type.GetType(propertyValue, true); - case StorageType.UInt16: - return XmlConvert.ToUInt16(propertyValue); - case StorageType.UInt32: - return XmlConvert.ToUInt32(propertyValue); - case StorageType.UInt64: - return XmlConvert.ToUInt64(propertyValue); - case StorageType.Uri: - return ClientConvert.CreateUri(propertyValue, UriKind.RelativeOrAbsolute); - case StorageType.XDocument: - return 0 < propertyValue.Length ? System.Xml.Linq.XDocument.Parse(propertyValue) : new System.Xml.Linq.XDocument(); - case StorageType.XElement: - return System.Xml.Linq.XElement.Parse(propertyValue); -#if !ASTORIA_LIGHT - case StorageType.Binary: - // Debug.Assert(null != KnownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); - return Activator.CreateInstance(KnownTypes[(int)StorageType.Binary], Convert.FromBase64String(propertyValue)); -#endif - default: - // Debug.Assert(false, "new StorageType without update to knownTypes"); - return propertyValue; - } - } - catch (FormatException ex) - { - propertyValue = 0 == propertyValue.Length ? "String.Empty" : "String"; - throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "The current value '{1}' type is not compatible with the expected '{0}' type.", propertyType.ToString(), propertyValue), ex); - } - catch (OverflowException ex) - { - propertyValue = 0 == propertyValue.Length ? "String.Empty" : "String"; - throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "The current value '{1}' type is not compatible with the expected '{0}' type.", propertyType.ToString(), propertyValue), ex); // Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex); - } - } - -#if !ASTORIA_LIGHT - internal static bool IsBinaryValue(object value) - { - // Debug.Assert(value != null, "value != null"); - return StorageType.Binary == (StorageType)IndexOfStorage(value.GetType()); - } - - internal static bool TryKeyBinaryToString(object binaryValue, out string result) - { - // Debug.Assert(binaryValue != null, "binaryValue != null"); - // Debug.Assert(IsBinaryValue(binaryValue), "IsBinaryValue(binaryValue) - otherwise TryKeyBinaryToString shouldn't have been called."); - const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod; - byte[] bytes = (byte[])binaryValue.GetType().InvokeMember("ToArray", Flags, null, binaryValue, null, null /* ParamModifiers */, System.Globalization.CultureInfo.InvariantCulture, null /* NamedParams */); - return Microsoft.WindowsAzure.Storage.Table.Queryable.WebConvert.TryKeyPrimitiveToString(bytes, out result); - } -#endif - - internal static bool TryKeyPrimitiveToString(object value, out string result) - { - // Debug.Assert(value != null, "value != null"); -#if !ASTORIA_LIGHT - if (IsBinaryValue(value)) - { - return TryKeyBinaryToString(value, out result); - } -#endif - // Support DateTimeOffset - if (value is DateTimeOffset) - { - value = ((DateTimeOffset)value).UtcDateTime; - } - else if (value is DateTimeOffset?) - { - value = ((DateTimeOffset?)value).Value.UtcDateTime; - } - - return Microsoft.WindowsAzure.Storage.Table.Queryable.WebConvert.TryKeyPrimitiveToString(value, out result); - } - - internal static bool ToNamedType(string typeName, out Type type) - { - type = typeof(string); - return string.IsNullOrEmpty(typeName) || ClientConvert.NamedTypesMap.TryGetValue(typeName, out type); - } - - internal static string ToTypeName(Type type) - { - // Debug.Assert(type != null, "type != null"); - foreach (var pair in ClientConvert.NamedTypesMap) - { - if (pair.Value == type) - { - return pair.Key; - } - } - - return type.FullName; - } - - internal static string ToString(object propertyValue, bool atomDateConstruct) - { - // Debug.Assert(null != propertyValue, "null should be handled by caller"); - switch ((StorageType)IndexOfStorage(propertyValue.GetType())) - { - case StorageType.Boolean: - return XmlConvert.ToString((bool)propertyValue); - case StorageType.Byte: - return XmlConvert.ToString((byte)propertyValue); - case StorageType.ByteArray: - return Convert.ToBase64String((byte[])propertyValue); - case StorageType.Char: - return XmlConvert.ToString((char)propertyValue); - case StorageType.CharArray: - return new string((char[])propertyValue); - case StorageType.DateTime: - DateTime dt = (DateTime)propertyValue; - return XmlConvert.ToString(dt.Kind == DateTimeKind.Unspecified && atomDateConstruct ? new DateTime(dt.Ticks, DateTimeKind.Utc) : dt, XmlDateTimeSerializationMode.RoundtripKind); - case StorageType.DateTimeOffset: - return XmlConvert.ToString((DateTimeOffset)propertyValue); - case StorageType.Decimal: - return XmlConvert.ToString((decimal)propertyValue); - case StorageType.Double: - return XmlConvert.ToString((double)propertyValue); - case StorageType.Guid: - return ((Guid)propertyValue).ToString(); - case StorageType.Int16: - return XmlConvert.ToString((short)propertyValue); - case StorageType.Int32: - return XmlConvert.ToString((int)propertyValue); - case StorageType.Int64: - return XmlConvert.ToString((long)propertyValue); - case StorageType.Single: - return XmlConvert.ToString((float)propertyValue); - case StorageType.String: - return (string)propertyValue; - case StorageType.SByte: - return XmlConvert.ToString((sbyte)propertyValue); - case StorageType.TimeSpan: - return XmlConvert.ToString((TimeSpan)propertyValue); - case StorageType.Type: - return ((Type)propertyValue).AssemblyQualifiedName; - case StorageType.UInt16: - return XmlConvert.ToString((ushort)propertyValue); - case StorageType.UInt32: - return XmlConvert.ToString((uint)propertyValue); - case StorageType.UInt64: - return XmlConvert.ToString((ulong)propertyValue); - case StorageType.Uri: - return ((Uri)propertyValue).ToString(); - case StorageType.XDocument: - return ((System.Xml.Linq.XDocument)propertyValue).ToString(); - case StorageType.XElement: - return ((System.Xml.Linq.XElement)propertyValue).ToString(); -#if !ASTORIA_LIGHT - case StorageType.Binary: - // Debug.Assert(null != KnownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); - // Debug.Assert(KnownTypes[(int)StorageType.Binary].IsInstanceOfType(propertyValue), "not IsInstanceOfType System.Data.Linq.Binary"); - return propertyValue.ToString(); -#endif - default: - // Debug.Assert(false, "new StorageType without update to knownTypes"); - return propertyValue.ToString(); - } - } - - internal static bool IsKnownType(Type type) - { - return 0 <= IndexOfStorage(type); - } - - internal static bool IsKnownNullableType(Type type) - { - return IsKnownType(Nullable.GetUnderlyingType(type) ?? type); - } - - internal static bool IsSupportedPrimitiveTypeForUri(Type type) - { - return ClientConvert.ContainsReference(NamedTypesMap.Values.ToArray(), type); - } - - internal static bool ContainsReference(T[] array, T value) where T : class - { - return 0 <= IndexOfReference(array, value); - } - - internal static string GetEdmType(Type propertyType) - { - switch ((StorageType)IndexOfStorage(propertyType)) - { - case StorageType.Boolean: - return XmlConstants.EdmBooleanTypeName; - case StorageType.Byte: - return XmlConstants.EdmByteTypeName; -#if !ASTORIA_LIGHT - case StorageType.Binary: -#endif - case StorageType.ByteArray: - return XmlConstants.EdmBinaryTypeName; - case StorageType.DateTime: - return XmlConstants.EdmDateTimeTypeName; - case StorageType.Decimal: - return XmlConstants.EdmDecimalTypeName; - case StorageType.Double: - return XmlConstants.EdmDoubleTypeName; - case StorageType.Guid: - return XmlConstants.EdmGuidTypeName; - case StorageType.Int16: - return XmlConstants.EdmInt16TypeName; - case StorageType.Int32: - return XmlConstants.EdmInt32TypeName; - case StorageType.Int64: - return XmlConstants.EdmInt64TypeName; - case StorageType.Single: - return XmlConstants.EdmSingleTypeName; - case StorageType.SByte: - return XmlConstants.EdmSByteTypeName; - case StorageType.DateTimeOffset: - case StorageType.TimeSpan: - case StorageType.UInt16: - case StorageType.UInt32: - case StorageType.UInt64: - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantCastToUnsupportedPrimitive, propertyType.Name)); - case StorageType.Char: - case StorageType.CharArray: - case StorageType.String: - case StorageType.Type: - case StorageType.Uri: - case StorageType.XDocument: - case StorageType.XElement: - return null; - default: - // Debug.Assert(false, "knowntype without reverse mapping"); - return null; - } - } - - private static Type[] CreateKnownPrimitives() - { -#if !ASTORIA_LIGHT - Type[] types = new Type[1 + (int)StorageType.Binary]; -#else - Type[] types = new Type[1 + (int)StorageType.XElement]; -#endif - types[(int)StorageType.Boolean] = typeof(bool); - types[(int)StorageType.Byte] = typeof(byte); - types[(int)StorageType.ByteArray] = typeof(byte[]); - types[(int)StorageType.Char] = typeof(char); - types[(int)StorageType.CharArray] = typeof(char[]); - types[(int)StorageType.DateTime] = typeof(DateTime); - types[(int)StorageType.DateTimeOffset] = typeof(DateTimeOffset); - types[(int)StorageType.Decimal] = typeof(decimal); - types[(int)StorageType.Double] = typeof(double); - types[(int)StorageType.Guid] = typeof(Guid); - types[(int)StorageType.Int16] = typeof(short); - types[(int)StorageType.Int32] = typeof(int); - types[(int)StorageType.Int64] = typeof(long); - types[(int)StorageType.Single] = typeof(float); - types[(int)StorageType.String] = typeof(string); - types[(int)StorageType.SByte] = typeof(sbyte); - types[(int)StorageType.TimeSpan] = typeof(TimeSpan); - types[(int)StorageType.Type] = typeof(Type); - types[(int)StorageType.UInt16] = typeof(ushort); - types[(int)StorageType.UInt32] = typeof(uint); - types[(int)StorageType.UInt64] = typeof(ulong); - types[(int)StorageType.Uri] = typeof(Uri); - types[(int)StorageType.XDocument] = typeof(System.Xml.Linq.XDocument); - types[(int)StorageType.XElement] = typeof(System.Xml.Linq.XElement); -#if !ASTORIA_LIGHT - types[(int)StorageType.Binary] = null; -#endif - return types; - } - - private static Dictionary CreateKnownNamesMap() - { - Dictionary named = new Dictionary(EqualityComparer.Default); - - named.Add(XmlConstants.EdmStringTypeName, typeof(string)); - named.Add(XmlConstants.EdmBooleanTypeName, typeof(bool)); - named.Add(XmlConstants.EdmByteTypeName, typeof(byte)); - named.Add(XmlConstants.EdmDateTimeTypeName, typeof(DateTime)); - named.Add(XmlConstants.EdmDecimalTypeName, typeof(decimal)); - named.Add(XmlConstants.EdmDoubleTypeName, typeof(double)); - named.Add(XmlConstants.EdmGuidTypeName, typeof(Guid)); - named.Add(XmlConstants.EdmInt16TypeName, typeof(short)); - named.Add(XmlConstants.EdmInt32TypeName, typeof(int)); - named.Add(XmlConstants.EdmInt64TypeName, typeof(long)); - named.Add(XmlConstants.EdmSByteTypeName, typeof(sbyte)); - named.Add(XmlConstants.EdmSingleTypeName, typeof(float)); - named.Add(XmlConstants.EdmBinaryTypeName, typeof(byte[])); - return named; - } - - private static int IndexOfStorage(Type type) - { - int index = ClientConvert.IndexOfReference(ClientConvert.KnownTypes, type); -#if !ASTORIA_LIGHT - if ((index < 0) && needSystemDataLinqBinary && (type.Name == "Binary")) - { - return LoadSystemDataLinqBinary(type); - } -#endif - return index; - } - - internal static int IndexOfReference(T[] array, T value) where T : class - { - // Debug.Assert(null != array, "null array"); - for (int i = 0; i < array.Length; ++i) - { - if (object.ReferenceEquals(array[i], value)) - { - return i; - } - } - - return -1; - } - - internal static Uri CreateUri(string value, UriKind kind) - { - return value == null ? null : new Uri(value, kind); - } - -#if !ASTORIA_LIGHT - private static int LoadSystemDataLinqBinary(Type type) - { - if (type.Namespace == "System.Data.Linq" && - System.Reflection.AssemblyName.ReferenceMatchesDefinition(type.Assembly.GetName(), new System.Reflection.AssemblyName(SystemDataLinq))) - { - ClientConvert.KnownTypes[(int)StorageType.Binary] = type; - needSystemDataLinqBinary = false; - return (int)StorageType.Binary; - } - - return -1; - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Common.cs deleted file mode 100644 index ce9742e9fdfb9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Common.cs +++ /dev/null @@ -1,62 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq; - - internal static class CommonUtil - { - private static readonly Type[] UnsupportedTypes = new Type[] - { -#if !ASTORIA_LIGHT - typeof(System.Dynamic.IDynamicMetaObjectProvider), - typeof(System.Tuple<>), - typeof(System.Tuple<,>), - typeof(System.Tuple<,,>), - typeof(System.Tuple<,,,>), - typeof(System.Tuple<,,,,>), - typeof(System.Tuple<,,,,,>), - typeof(System.Tuple<,,,,,,>), - typeof(System.Tuple<,,,,,,,>) -#endif - }; - - internal static bool IsUnsupportedType(Type type) - { - if (type.IsGenericType) - { - type = type.GetGenericTypeDefinition(); - } - - if (UnsupportedTypes.Any(t => t.IsAssignableFrom(type))) - { - return true; - } - - Debug.Assert(!type.FullName.StartsWith("System.Tuple", StringComparison.Ordinal), "System.Tuple is not blocked by unsupported type check"); - return false; - } - - internal static bool IsClientType(Type t) - { - return t.GetInterface(typeof(ITableEntity).FullName, false) != null; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/DataServiceExpressionVisitor.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/DataServiceExpressionVisitor.cs deleted file mode 100644 index f269c89de3063..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/DataServiceExpressionVisitor.cs +++ /dev/null @@ -1,80 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System.Linq.Expressions; - - #endregion Namespaces. - - internal abstract class DataServiceALinqExpressionVisitor : ALinqExpressionVisitor - { - internal override Expression Visit(Expression exp) - { - if (exp == null) - { - return null; - } - - switch ((ResourceExpressionType)exp.NodeType) - { - case ResourceExpressionType.RootResourceSet: - case ResourceExpressionType.ResourceNavigationProperty: - return this.VisitResourceSetExpression((ResourceSetExpression)exp); - case ResourceExpressionType.ResourceNavigationPropertySingleton: - return this.VisitNavigationPropertySingletonExpression((NavigationPropertySingletonExpression)exp); - case ResourceExpressionType.InputReference: - return this.VisitInputReferenceExpression((InputReferenceExpression)exp); - default: - return base.Visit(exp); - } - } - - internal virtual Expression VisitResourceSetExpression(ResourceSetExpression rse) - { - Expression source = this.Visit(rse.Source); - - if (source != rse.Source) - { - rse = new ResourceSetExpression(rse.Type, source, rse.MemberExpression, rse.ResourceType, rse.ExpandPaths, rse.CountOption, rse.CustomQueryOptions, rse.Projection); - } - - return rse; - } - - internal virtual Expression VisitNavigationPropertySingletonExpression(NavigationPropertySingletonExpression npse) - { - Expression source = this.Visit(npse.Source); - - if (source != npse.Source) - { - npse = new NavigationPropertySingletonExpression(npse.Type, source, npse.MemberExpression, npse.MemberExpression.Type, npse.ExpandPaths, npse.CountOption, npse.CustomQueryOptions, npse.Projection); - } - - return npse; - } - - internal virtual Expression VisitInputReferenceExpression(InputReferenceExpression ire) - { - // Debug.Assert(ire != null, "ire != null -- otherwise caller never should have visited here"); - ResourceExpression re = (ResourceExpression)this.Visit(ire.Target); - return re.CreateReference(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/EntityResolverQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/EntityResolverQueryOptionExpression.cs deleted file mode 100644 index 042593fff36e3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/EntityResolverQueryOptionExpression.cs +++ /dev/null @@ -1,43 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq.Expressions; - - [DebuggerDisplay("EntityResolverQueryOptionExpression {requestOptions}")] - internal class EntityResolverQueryOptionExpression : QueryOptionExpression - { - private ConstantExpression resolver; - - internal EntityResolverQueryOptionExpression(Type type, ConstantExpression resolver) - : base((ExpressionType)ResourceExpressionType.Resolver, type) - { - this.resolver = resolver; - } - - internal ConstantExpression Resolver - { - get - { - return this.resolver; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Evaluator.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Evaluator.cs deleted file mode 100644 index 2161872ffef80..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/Evaluator.cs +++ /dev/null @@ -1,149 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq.Expressions; - - internal static class Evaluator - { - internal static Expression PartialEval(Expression expression, Func canBeEvaluated) - { - Nominator nominator = new Nominator(canBeEvaluated); - HashSet candidates = nominator.Nominate(expression); - return new SubtreeEvaluator(candidates).Eval(expression); - } - - internal static Expression PartialEval(Expression expression) - { - return PartialEval(expression, Evaluator.CanBeEvaluatedLocally); - } - - private static bool CanBeEvaluatedLocally(Expression expression) - { - return expression.NodeType != ExpressionType.Parameter && - expression.NodeType != ExpressionType.Lambda - && expression.NodeType != (ExpressionType)ResourceExpressionType.RootResourceSet; - } - - internal class SubtreeEvaluator : DataServiceALinqExpressionVisitor - { - private HashSet candidates; - - internal SubtreeEvaluator(HashSet candidates) - { - this.candidates = candidates; - } - - internal Expression Eval(Expression exp) - { - return this.Visit(exp); - } - - internal override Expression Visit(Expression exp) - { - if (exp == null) - { - return null; - } - - if (this.candidates.Contains(exp)) - { - return Evaluate(exp); - } - - return base.Visit(exp); - } - - private static Expression Evaluate(Expression e) - { - if (e.NodeType == ExpressionType.Constant) - { - return e; - } - -#if ASTORIA_LIGHT - LambdaExpression lambda = ExpressionHelpers.CreateLambda(e, new ParameterExpression[0]); -#else - LambdaExpression lambda = Expression.Lambda(e); -#endif - Delegate fn = lambda.Compile(); - object constantValue = fn.DynamicInvoke(null); - Debug.Assert(!(constantValue is Expression), "!(constantValue is Expression)"); - - Type constantType = e.Type; - if (constantValue != null && constantType.IsArray && constantType.GetElementType() == constantValue.GetType().GetElementType()) - { - constantType = constantValue.GetType(); - } - - return Expression.Constant(constantValue, constantType); - } - } - - internal class Nominator : DataServiceALinqExpressionVisitor - { - private Func functionCanBeEvaluated; - - private HashSet candidates; - - private bool cannotBeEvaluated; - - internal Nominator(Func functionCanBeEvaluated) - { - this.functionCanBeEvaluated = functionCanBeEvaluated; - } - - internal HashSet Nominate(Expression expression) - { - this.candidates = new HashSet(EqualityComparer.Default); - this.Visit(expression); - return this.candidates; - } - - internal override Expression Visit(Expression expression) - { - if (expression != null) - { - bool saveCannotBeEvaluated = this.cannotBeEvaluated; - this.cannotBeEvaluated = false; - - base.Visit(expression); - - if (!this.cannotBeEvaluated) - { - if (this.functionCanBeEvaluated(expression)) - { - this.candidates.Add(expression); - } - else - { - this.cannotBeEvaluated = true; - } - } - - this.cannotBeEvaluated |= saveCannotBeEvaluated; - } - - return expression; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionNormalizer.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionNormalizer.cs deleted file mode 100644 index 3a0def225602a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionNormalizer.cs +++ /dev/null @@ -1,461 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq.Expressions; - using System.Reflection; - - #endregion Namespaces. - - internal class ExpressionNormalizer : DataServiceALinqExpressionVisitor - { - #region Private fields. - - private const bool LiftToNull = false; - - private readonly Dictionary patterns = new Dictionary(ReferenceEqualityComparer.Instance); - - private readonly Dictionary normalizerRewrites; - - #endregion Private fields. - - #region Constructors. - - private ExpressionNormalizer(Dictionary normalizerRewrites) - { - Debug.Assert(normalizerRewrites != null, "normalizerRewrites != null"); - this.normalizerRewrites = normalizerRewrites; - } - - #endregion Constructors. - - #region Internal properties. - - internal Dictionary NormalizerRewrites - { - get { return this.normalizerRewrites; } - } - - #endregion Internal properties. - - internal static Expression Normalize(Expression expression, Dictionary rewrites) - { - Debug.Assert(expression != null, "expression != null"); - Debug.Assert(rewrites != null, "rewrites != null"); - - ExpressionNormalizer normalizer = new ExpressionNormalizer(rewrites); - Expression result = normalizer.Visit(expression); - return result; - } - - internal override Expression VisitBinary(BinaryExpression b) - { - BinaryExpression visited = (BinaryExpression)base.VisitBinary(b); - - if (visited.NodeType == ExpressionType.Equal) - { - Expression normalizedLeft = UnwrapObjectConvert(visited.Left); - Expression normalizedRight = UnwrapObjectConvert(visited.Right); - if (normalizedLeft != visited.Left || normalizedRight != visited.Right) - { - visited = CreateRelationalOperator(ExpressionType.Equal, normalizedLeft, normalizedRight); - } - } - - Pattern pattern; - if (this.patterns.TryGetValue(visited.Left, out pattern) && pattern.Kind == PatternKind.Compare && IsConstantZero(visited.Right)) - { - ComparePattern comparePattern = (ComparePattern)pattern; - BinaryExpression relationalExpression; - if (TryCreateRelationalOperator(visited.NodeType, comparePattern.Left, comparePattern.Right, out relationalExpression)) - { - visited = relationalExpression; - } - } - - this.RecordRewrite(b, visited); - - return visited; - } - - internal override Expression VisitUnary(UnaryExpression u) - { - UnaryExpression visited = (UnaryExpression)base.VisitUnary(u); - Expression result = visited; - - this.RecordRewrite(u, result); - - return result; - } - - private static Expression UnwrapObjectConvert(Expression input) - { - if (input.NodeType == ExpressionType.Constant && input.Type == typeof(object)) - { - ConstantExpression constant = (ConstantExpression)input; - - if (constant.Value != null && - constant.Value.GetType() != typeof(object)) - { - return Expression.Constant(constant.Value, constant.Value.GetType()); - } - } - - while (ExpressionType.Convert == input.NodeType && typeof(object) == input.Type) - { - input = ((UnaryExpression)input).Operand; - } - - return input; - } - - private static bool IsConstantZero(Expression expression) - { - return expression.NodeType == ExpressionType.Constant && - ((ConstantExpression)expression).Value.Equals(0); - } - - internal override Expression VisitMethodCall(MethodCallExpression call) - { - Expression visited = this.VisitMethodCallNoRewrite(call); - this.RecordRewrite(call, visited); - return visited; - } - - internal Expression VisitMethodCallNoRewrite(MethodCallExpression call) - { - MethodCallExpression visited = (MethodCallExpression)base.VisitMethodCall(call); - - if (visited.Method.IsStatic && visited.Method.Name.StartsWith("op_", StringComparison.Ordinal)) - { - if (visited.Arguments.Count == 2) - { - switch (visited.Method.Name) - { - case "op_Equality": - return Expression.Equal(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_Inequality": - return Expression.NotEqual(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_GreaterThan": - return Expression.GreaterThan(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_GreaterThanOrEqual": - return Expression.GreaterThanOrEqual(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_LessThan": - return Expression.LessThan(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_LessThanOrEqual": - return Expression.LessThanOrEqual(visited.Arguments[0], visited.Arguments[1], LiftToNull, visited.Method); - - case "op_Multiply": - return Expression.Multiply(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_Subtraction": - return Expression.Subtract(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_Addition": - return Expression.Add(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_Division": - return Expression.Divide(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_Modulus": - return Expression.Modulo(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_BitwiseAnd": - return Expression.And(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_BitwiseOr": - return Expression.Or(visited.Arguments[0], visited.Arguments[1], visited.Method); - - case "op_ExclusiveOr": - return Expression.ExclusiveOr(visited.Arguments[0], visited.Arguments[1], visited.Method); - - default: - break; - } - } - - if (visited.Arguments.Count == 1) - { - switch (visited.Method.Name) - { - case "op_UnaryNegation": - return Expression.Negate(visited.Arguments[0], visited.Method); - - case "op_UnaryPlus": - return Expression.UnaryPlus(visited.Arguments[0], visited.Method); - - case "op_Explicit": - case "op_Implicit": - return Expression.Convert(visited.Arguments[0], visited.Type, visited.Method); - - case "op_OnesComplement": - case "op_False": - return Expression.Not(visited.Arguments[0], visited.Method); - - default: - break; - } - } - } - - if (visited.Method.IsStatic && visited.Method.Name == "Equals" && visited.Arguments.Count > 1) - { - return Expression.Equal(visited.Arguments[0], visited.Arguments[1], false, visited.Method); - } - - if (!visited.Method.IsStatic && visited.Method.Name == "Equals" && visited.Arguments.Count > 0) - { - return CreateRelationalOperator(ExpressionType.Equal, visited.Object, visited.Arguments[0]); - } - - if (visited.Method.IsStatic && visited.Method.Name == "CompareString" && visited.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators") - { - return this.CreateCompareExpression(visited.Arguments[0], visited.Arguments[1]); - } - - if (!visited.Method.IsStatic && visited.Method.Name == "CompareTo" && visited.Arguments.Count == 1 && visited.Method.ReturnType == typeof(int)) - { - return this.CreateCompareExpression(visited.Object, visited.Arguments[0]); - } - - if (visited.Method.IsStatic && visited.Method.Name == "Compare" && visited.Arguments.Count > 1 && visited.Method.ReturnType == typeof(int)) - { - return this.CreateCompareExpression(visited.Arguments[0], visited.Arguments[1]); - } - - MethodCallExpression normalizedResult = NormalizePredicateArgument(visited); - - return normalizedResult; - } - - private static MethodCallExpression NormalizePredicateArgument(MethodCallExpression callExpression) - { - MethodCallExpression result; - - int argumentOrdinal; - Expression normalizedArgument; - if (HasPredicateArgument(callExpression, out argumentOrdinal) && - TryMatchCoalescePattern(callExpression.Arguments[argumentOrdinal], out normalizedArgument)) - { - List normalizedArguments = new List(callExpression.Arguments); - - normalizedArguments[argumentOrdinal] = normalizedArgument; - - result = Expression.Call(callExpression.Object, callExpression.Method, normalizedArguments); - } - else - { - result = callExpression; - } - - return result; - } - - private static bool HasPredicateArgument(MethodCallExpression callExpression, out int argumentOrdinal) - { - argumentOrdinal = default(int); - bool result = false; - - SequenceMethod sequenceMethod; - if (2 <= callExpression.Arguments.Count && - ReflectionUtil.TryIdentifySequenceMethod(callExpression.Method, out sequenceMethod)) - { - switch (sequenceMethod) - { - case SequenceMethod.FirstPredicate: - case SequenceMethod.FirstOrDefaultPredicate: - case SequenceMethod.SinglePredicate: - case SequenceMethod.SingleOrDefaultPredicate: - case SequenceMethod.LastPredicate: - case SequenceMethod.LastOrDefaultPredicate: - case SequenceMethod.Where: - case SequenceMethod.WhereOrdinal: - case SequenceMethod.CountPredicate: - case SequenceMethod.LongCountPredicate: - case SequenceMethod.AnyPredicate: - case SequenceMethod.All: - case SequenceMethod.SkipWhile: - case SequenceMethod.SkipWhileOrdinal: - case SequenceMethod.TakeWhile: - case SequenceMethod.TakeWhileOrdinal: - argumentOrdinal = 1; - result = true; - break; - } - } - - return result; - } - - private static bool TryMatchCoalescePattern(Expression expression, out Expression normalized) - { - normalized = null; - bool result = false; - - if (expression.NodeType == ExpressionType.Quote) - { - UnaryExpression quote = (UnaryExpression)expression; - if (TryMatchCoalescePattern(quote.Operand, out normalized)) - { - result = true; - normalized = Expression.Quote(normalized); - } - } - else if (expression.NodeType == ExpressionType.Lambda) - { - LambdaExpression lambda = (LambdaExpression)expression; - - if (lambda.Body.NodeType == ExpressionType.Coalesce && lambda.Body.Type == typeof(bool)) - { - BinaryExpression coalesce = (BinaryExpression)lambda.Body; - if (coalesce.Right.NodeType == ExpressionType.Constant && false.Equals(((ConstantExpression)coalesce.Right).Value)) - { - normalized = Expression.Lambda(lambda.Type, Expression.Convert(coalesce.Left, typeof(bool)), lambda.Parameters); - result = true; - } - } - } - - return result; - } - - private static readonly MethodInfo StaticRelationalOperatorPlaceholderMethod = typeof(ExpressionNormalizer).GetMethod("RelationalOperatorPlaceholder", BindingFlags.Static | BindingFlags.NonPublic); - - private static bool RelationalOperatorPlaceholder(TLeft left, TRight right) - { - Debug.Assert(false, "This method should never be called. It exists merely to support creation of relational LINQ expressions."); - return object.ReferenceEquals(left, right); - } - - private static BinaryExpression CreateRelationalOperator(ExpressionType op, Expression left, Expression right) - { - BinaryExpression result; - if (!TryCreateRelationalOperator(op, left, right, out result)) - { - Debug.Assert(false, "CreateRelationalOperator has unknown op " + op); - } - - return result; - } - - private static bool TryCreateRelationalOperator(ExpressionType op, Expression left, Expression right, out BinaryExpression result) - { - MethodInfo relationalOperatorPlaceholderMethod = StaticRelationalOperatorPlaceholderMethod.MakeGenericMethod(left.Type, right.Type); - - switch (op) - { - case ExpressionType.Equal: - result = Expression.Equal(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - case ExpressionType.NotEqual: - result = Expression.NotEqual(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - case ExpressionType.LessThan: - result = Expression.LessThan(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - case ExpressionType.LessThanOrEqual: - result = Expression.LessThanOrEqual(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - case ExpressionType.GreaterThan: - result = Expression.GreaterThan(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - case ExpressionType.GreaterThanOrEqual: - result = Expression.GreaterThanOrEqual(left, right, LiftToNull, relationalOperatorPlaceholderMethod); - return true; - - default: - result = null; - return false; - } - } - - private Expression CreateCompareExpression(Expression left, Expression right) - { - Expression result = Expression.Condition( - CreateRelationalOperator(ExpressionType.Equal, left, right), - Expression.Constant(0), - Expression.Condition( - CreateRelationalOperator(ExpressionType.GreaterThan, left, right), - Expression.Constant(1), - Expression.Constant(-1))); - - this.patterns[result] = new ComparePattern(left, right); - - return result; - } - - private void RecordRewrite(Expression source, Expression rewritten) - { - Debug.Assert(source != null, "source != null"); - Debug.Assert(rewritten != null, "rewritten != null"); - Debug.Assert(this.NormalizerRewrites != null, "this.NormalizerRewrites != null"); - - if (source != rewritten) - { - this.NormalizerRewrites.Add(rewritten, source); - } - } - - #region Inner types. - - private abstract class Pattern - { - internal abstract PatternKind Kind { get; } - } - - private enum PatternKind - { - Compare, - } - - private sealed class ComparePattern : Pattern - { - internal ComparePattern(Expression left, Expression right) - { - this.Left = left; - this.Right = right; - } - - internal readonly Expression Left; - - internal readonly Expression Right; - - internal override PatternKind Kind - { - get { return PatternKind.Compare; } - } - } - - #endregion Inner types. - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionParser.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionParser.cs deleted file mode 100644 index 4d9bf0067688d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionParser.cs +++ /dev/null @@ -1,313 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq.Expressions; - - #endregion Namespaces. - - internal class ExpressionParser : DataServiceALinqExpressionVisitor - { - #region Properties - internal TableRequestOptions RequestOptions { get; set; } - - internal OperationContext OperationContext { get; set; } - - internal ConstantExpression Resolver { get; set; } - - internal ProjectionQueryOptionExpression Projection { get; set; } - - private int? takeCount = null; - - /// - /// Gets or sets the number of entities the table query will return. - /// - /// The maximum number of entities for the table query to return. - public int? TakeCount - { - get - { - return this.takeCount; - } - - set - { - if (value.HasValue && value.Value <= 0) - { - throw new ArgumentException(SR.TakeCountNotPositive); - } - - this.takeCount = value; - } - } - - /// - /// Gets or sets the filter expression to use in the table query. - /// - /// A string containing the filter expression to use in the query. - public string FilterString { get; set; } - - /// - /// Gets or sets the property names of the table entity properties to return when the table query is executed. - /// - /// A list of strings containing the property names of the table entity properties to return when the query is executed. - public IList SelectColumns { get; set; } - #endregion - - internal ExpressionParser() - { - this.SelectColumns = new List(); - } - - internal void Translate(Expression e) - { - this.Visit(e); - } - - #region Not Supported Call Expressions - internal override Expression VisitMethodCall(MethodCallExpression m) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "The method '{0}' is not supported.", m.Method.Name)); // Error.MethodNotSupported(m); - } - - internal override Expression VisitUnary(UnaryExpression u) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqUnaryNotSupported, u.NodeType.ToString())); - } - - internal override Expression VisitBinary(BinaryExpression b) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqBinaryNotSupported, b.NodeType.ToString())); - } - - internal override Expression VisitConstant(ConstantExpression c) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqConstantNotSupported, c.Value)); - } - - internal override Expression VisitTypeIs(TypeBinaryExpression b) - { - throw new NotSupportedException(SR.ALinqTypeBinaryNotSupported); - } - - internal override Expression VisitConditional(ConditionalExpression c) - { - throw new NotSupportedException(SR.ALinqConditionalNotSupported); - } - - internal override Expression VisitParameter(ParameterExpression p) - { - throw new NotSupportedException(SR.ALinqParameterNotSupported); - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqMemberAccessNotSupported, m.Member.Name)); - } - - internal override Expression VisitLambda(LambdaExpression lambda) - { - throw new NotSupportedException(SR.ALinqLambdaNotSupported); - } - - internal override NewExpression VisitNew(NewExpression nex) - { - throw new NotSupportedException(SR.ALinqNewNotSupported); - } - - internal override Expression VisitMemberInit(MemberInitExpression init) - { - throw new NotSupportedException(SR.ALinqMemberInitNotSupported); - } - - internal override Expression VisitListInit(ListInitExpression init) - { - throw new NotSupportedException(SR.ALinqListInitNotSupported); - } - - internal override Expression VisitNewArray(NewArrayExpression na) - { - throw new NotSupportedException(SR.ALinqNewArrayNotSupported); - } - - internal override Expression VisitInvocation(InvocationExpression iv) - { - throw new NotSupportedException(SR.ALinqInvocationNotSupported); - } - #endregion - - internal override Expression VisitNavigationPropertySingletonExpression(NavigationPropertySingletonExpression npse) - { - throw new NotSupportedException("Navigation not supported."); - } - - internal override Expression VisitResourceSetExpression(ResourceSetExpression rse) - { - /* if ((ResourceExpressionType)rse.NodeType == ResourceExpressionType.ResourceNavigationProperty) - { - this.Visit(rse.Source); - this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(this.ExpressionToString(rse.MemberExpression)); - } - else - { - this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append((string)((ConstantExpression)rse.MemberExpression).Value); - } - - TODO optimize for point query - if (rse.KeyPredicate != null) - { - this.uriBuilder.Append(UriHelper.LEFTPAREN); - if (rse.KeyPredicate.Count == 1) - { - this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First())); - } - else - { - bool addComma = false; - foreach (var kvp in rse.KeyPredicate) - { - if (addComma) - { - this.uriBuilder.Append(UriHelper.COMMA); - } - - this.uriBuilder.Append(kvp.Key.Name); - this.uriBuilder.Append(UriHelper.EQUALSSIGN); - this.uriBuilder.Append(this.ExpressionToString(kvp.Value)); - addComma = true; - } - } - - this.uriBuilder.Append(UriHelper.RIGHTPAREN); - } - else if (rse == this.leafResourceSet) - { - this.uriBuilder.Append(UriHelper.LEFTPAREN); - this.uriBuilder.Append(UriHelper.RIGHTPAREN); - } - - if (rse.CountOption == CountOption.ValueOnly) - { - this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT); - this.EnsureMinimumVersion(2, 0); - } - */ - this.VisitQueryOptions(rse); - return rse; - } - - internal void VisitQueryOptions(ResourceExpression re) - { - if (re.HasQueryOptions) - { - ResourceSetExpression rse = re as ResourceSetExpression; - if (rse != null) - { - IEnumerator options = rse.SequenceQueryOptions.GetEnumerator(); - while (options.MoveNext()) - { - Expression e = (Expression)options.Current; - ResourceExpressionType et = (ResourceExpressionType)e.NodeType; - switch (et) - { - case ResourceExpressionType.RequestOptions: - this.VisitQueryOptionExpression((RequestOptionsQueryOptionExpression)e); - break; - case ResourceExpressionType.OperationContext: - this.VisitQueryOptionExpression((OperationContextQueryOptionExpression)e); - break; - case ResourceExpressionType.Resolver: - this.VisitQueryOptionExpression((EntityResolverQueryOptionExpression)e); - break; - case ResourceExpressionType.TakeQueryOption: - this.VisitQueryOptionExpression((TakeQueryOptionExpression)e); - break; - case ResourceExpressionType.FilterQueryOption: - this.VisitQueryOptionExpression((FilterQueryOptionExpression)e); - break; - default: - Debug.Assert(false, "Unexpected expression type " + (int)et); - break; - } - } - } - - if (re.Projection != null && re.Projection.Paths.Count > 0) - { - this.Projection = re.Projection; - this.SelectColumns = re.Projection.Paths; - } - - if (re.CustomQueryOptions.Count > 0) - { - this.VisitCustomQueryOptions(re.CustomQueryOptions); - } - } - } - - internal void VisitQueryOptionExpression(RequestOptionsQueryOptionExpression roqoe) - { - this.RequestOptions = (TableRequestOptions)roqoe.RequestOptions.Value; - } - - internal void VisitQueryOptionExpression(OperationContextQueryOptionExpression ocqoe) - { - this.OperationContext = (OperationContext)ocqoe.OperationContext.Value; - } - - internal void VisitQueryOptionExpression(EntityResolverQueryOptionExpression erqoe) - { - this.Resolver = erqoe.Resolver; - } - - internal void VisitQueryOptionExpression(TakeQueryOptionExpression tqoe) - { - this.TakeCount = (int)tqoe.TakeAmount.Value; - } - - internal void VisitQueryOptionExpression(FilterQueryOptionExpression fqoe) - { - this.FilterString = ExpressionParser.ExpressionToString(fqoe.Predicate); - } - - /* - internal void VisitCountOptions() - { - throw new NotSupportedException("Count not supported."); - } - */ - - internal void VisitCustomQueryOptions(Dictionary options) - { - throw new NotSupportedException(); - } - - private static string ExpressionToString(Expression expression) - { - return ExpressionWriter.ExpressionToString(expression); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionWriter.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionWriter.cs deleted file mode 100644 index 069bbf147953a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ExpressionWriter.cs +++ /dev/null @@ -1,417 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq.Expressions; - using System.Reflection; - using System.Text; - - #endregion Namespaces. - - internal class ExpressionWriter : DataServiceALinqExpressionVisitor - { - #region Private fields. - - private readonly StringBuilder builder; - - private readonly Stack expressionStack; - - private bool cantTranslateExpression; - - private Expression parent; - - #endregion Private fields. - - private ExpressionWriter() - { - this.builder = new StringBuilder(); - this.expressionStack = new Stack(); - this.expressionStack.Push(null); - } - - internal static string ExpressionToString(Expression e) - { - ExpressionWriter ew = new ExpressionWriter(); - - string serialized = null; - serialized = ew.Translate(e); - - if (ew.cantTranslateExpression) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantTranslateExpression, e.ToString())); - } - - return serialized; - } - - internal override Expression Visit(Expression exp) - { - this.parent = this.expressionStack.Peek(); - this.expressionStack.Push(exp); - Expression result = base.Visit(exp); - this.expressionStack.Pop(); - return result; - } - - internal override Expression VisitConditional(ConditionalExpression c) - { - this.cantTranslateExpression = true; - return c; - } - - internal override Expression VisitLambda(LambdaExpression lambda) - { - this.cantTranslateExpression = true; - return lambda; - } - - internal override NewExpression VisitNew(NewExpression nex) - { - this.cantTranslateExpression = true; - return nex; - } - - internal override Expression VisitMemberInit(MemberInitExpression init) - { - this.cantTranslateExpression = true; - return init; - } - - internal override Expression VisitListInit(ListInitExpression init) - { - this.cantTranslateExpression = true; - return init; - } - - internal override Expression VisitNewArray(NewArrayExpression na) - { - this.cantTranslateExpression = true; - return na; - } - - internal override Expression VisitInvocation(InvocationExpression iv) - { - this.cantTranslateExpression = true; - return iv; - } - - internal override Expression VisitInputReferenceExpression(InputReferenceExpression ire) - { - Debug.Assert(ire != null, "ire != null"); - if (this.parent == null || this.parent.NodeType != ExpressionType.MemberAccess) - { - string expressionText = (this.parent != null) ? this.parent.ToString() : ire.ToString(); - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantTranslateExpression, expressionText)); - } - - return ire; - } - - internal override Expression VisitMethodCall(MethodCallExpression m) - { - string methodName; - if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName)) - { - this.builder.Append(methodName); - this.builder.Append(UriHelper.LEFTPAREN); - - if (methodName == "substringof") - { - Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'"); - Debug.Assert(m.Object != null, "m.Object != null"); - Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1"); - this.Visit(m.Arguments[0]); - this.builder.Append(UriHelper.COMMA); - this.Visit(m.Object); - } - else - { - if (m.Object != null) - { - this.Visit(m.Object); - } - - if (m.Arguments.Count > 0) - { - if (m.Object != null) - { - this.builder.Append(UriHelper.COMMA); - } - - for (int ii = 0; ii < m.Arguments.Count; ii++) - { - this.Visit(m.Arguments[ii]); - if (ii < m.Arguments.Count - 1) - { - this.builder.Append(UriHelper.COMMA); - } - } - } - } - - this.builder.Append(UriHelper.RIGHTPAREN); - } - else - { - this.cantTranslateExpression = true; - } - - return m; - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - if (m.Member is FieldInfo) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantReferToPublicField, m.Member.Name)); - } - - if (m.Member.DeclaringType == typeof(EntityProperty)) - { - MethodCallExpression mce = m.Expression as MethodCallExpression; - if (mce != null && mce.Arguments.Count == 1 && mce.Method == ReflectionUtil.DictionaryGetItemMethodInfo) - { - MemberExpression me = mce.Object as MemberExpression; - if (me != null && me.Member.DeclaringType == typeof(DynamicTableEntity) && me.Member.Name == "Properties") - { - // Append Property name arg to string - ConstantExpression ce = mce.Arguments[0] as ConstantExpression; - if (ce == null || !(ce.Value is string)) - { - throw new NotSupportedException(SR.TableQueryDynamicPropertyAccess); - } - - this.builder.Append((string)ce.Value); - return ce; - } - } - - throw new NotSupportedException(SR.TableQueryEntityPropertyInQueryNotSupported); - } - - Expression e = this.Visit(m.Expression); - - if (m.Member.Name == "Value" && m.Member.DeclaringType.IsGenericType - && m.Member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable<>)) - { - return m; - } - - if (!IsInputReference(e) && e.NodeType != ExpressionType.Convert && e.NodeType != ExpressionType.ConvertChecked) - { - this.builder.Append(UriHelper.FORWARDSLASH); - } - - this.builder.Append(m.Member.Name); - - return m; - } - - internal override Expression VisitConstant(ConstantExpression c) - { - string result = null; - if (c.Value == null) - { - this.builder.Append(UriHelper.NULL); - return c; - } - else if (!ClientConvert.TryKeyPrimitiveToString(c.Value, out result)) - { - throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCouldNotConvert, c.Value)); - } - - Debug.Assert(result != null, "result != null"); - - // A Difference from WCF Data Services is that we will escape later when we execute the fully parsed query. - this.builder.Append(result); - return c; - } - - internal override Expression VisitUnary(UnaryExpression u) - { - switch (u.NodeType) - { - case ExpressionType.Not: - this.builder.Append(UriHelper.NOT); - this.builder.Append(UriHelper.SPACE); - this.VisitOperand(u.Operand); - break; - case ExpressionType.Negate: - case ExpressionType.NegateChecked: - this.builder.Append(UriHelper.SPACE); - this.builder.Append(UriHelper.NEGATE); - this.VisitOperand(u.Operand); - break; - case ExpressionType.Convert: - case ExpressionType.ConvertChecked: - case ExpressionType.UnaryPlus: - break; - default: - this.cantTranslateExpression = true; - break; - } - - return u; - } - - internal override Expression VisitBinary(BinaryExpression b) - { - this.VisitOperand(b.Left); - this.builder.Append(UriHelper.SPACE); - switch (b.NodeType) - { - case ExpressionType.AndAlso: - case ExpressionType.And: - this.builder.Append(UriHelper.AND); - break; - case ExpressionType.OrElse: - case ExpressionType.Or: - this.builder.Append(UriHelper.OR); - break; - case ExpressionType.Equal: - this.builder.Append(UriHelper.EQ); - break; - case ExpressionType.NotEqual: - this.builder.Append(UriHelper.NE); - break; - case ExpressionType.LessThan: - this.builder.Append(UriHelper.LT); - break; - case ExpressionType.LessThanOrEqual: - this.builder.Append(UriHelper.LE); - break; - case ExpressionType.GreaterThan: - this.builder.Append(UriHelper.GT); - break; - case ExpressionType.GreaterThanOrEqual: - this.builder.Append(UriHelper.GE); - break; - case ExpressionType.Add: - case ExpressionType.AddChecked: - this.builder.Append(UriHelper.ADD); - break; - case ExpressionType.Subtract: - case ExpressionType.SubtractChecked: - this.builder.Append(UriHelper.SUB); - break; - case ExpressionType.Multiply: - case ExpressionType.MultiplyChecked: - this.builder.Append(UriHelper.MUL); - break; - case ExpressionType.Divide: - this.builder.Append(UriHelper.DIV); - break; - case ExpressionType.Modulo: - this.builder.Append(UriHelper.MOD); - break; - case ExpressionType.ArrayIndex: - case ExpressionType.Power: - case ExpressionType.Coalesce: - case ExpressionType.ExclusiveOr: - case ExpressionType.LeftShift: - case ExpressionType.RightShift: - default: - this.cantTranslateExpression = true; - break; - } - - this.builder.Append(UriHelper.SPACE); - this.VisitOperand(b.Right); - return b; - } - - internal override Expression VisitTypeIs(TypeBinaryExpression b) - { - this.builder.Append(UriHelper.ISOF); - this.builder.Append(UriHelper.LEFTPAREN); - - if (!IsInputReference(b.Expression)) - { - this.Visit(b.Expression); - this.builder.Append(UriHelper.COMMA); - this.builder.Append(UriHelper.SPACE); - } - - this.builder.Append(UriHelper.QUOTE); - this.builder.Append(this.TypeNameForUri(b.TypeOperand)); - this.builder.Append(UriHelper.QUOTE); - this.builder.Append(UriHelper.RIGHTPAREN); - - return b; - } - - internal override Expression VisitParameter(ParameterExpression p) - { - return p; - } - - private static bool IsInputReference(Expression exp) - { - return exp is InputReferenceExpression || exp is ParameterExpression; - } - - private string TypeNameForUri(Type type) - { - Debug.Assert(type != null, "type != null"); - type = Nullable.GetUnderlyingType(type) ?? type; - - if (ClientConvert.IsKnownType(type)) - { - if (ClientConvert.IsSupportedPrimitiveTypeForUri(type)) - { - return ClientConvert.ToTypeName(type); - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqCantCastToUnsupportedPrimitive, type.Name)); - } - else - { - return null; - - // return this.context.ResolveNameFromType(type) ?? type.FullName; - } - } - - private void VisitOperand(Expression e) - { - if (e is BinaryExpression || e is UnaryExpression) - { - this.builder.Append(UriHelper.LEFTPAREN); - this.Visit(e); - this.builder.Append(UriHelper.RIGHTPAREN); - } - else - { - this.Visit(e); - } - } - - private string Translate(Expression e) - { - this.Visit(e); - return this.builder.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/FilterQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/FilterQueryOptionExpression.cs deleted file mode 100644 index 9e08f78f34a43..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/FilterQueryOptionExpression.cs +++ /dev/null @@ -1,41 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Linq.Expressions; - - internal class FilterQueryOptionExpression : QueryOptionExpression - { - private Expression predicate; - - internal FilterQueryOptionExpression(Type type, Expression predicate) - : base((ExpressionType)ResourceExpressionType.FilterQueryOption, type) - { - this.predicate = predicate; - } - - internal Expression Predicate - { - get - { - return this.predicate; - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputBinder.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputBinder.cs deleted file mode 100644 index 673d400aeb572..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputBinder.cs +++ /dev/null @@ -1,173 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq.Expressions; - using System.Reflection; - - #endregion Namespaces. - - internal sealed class InputBinder : DataServiceALinqExpressionVisitor - { - #region Private fields. - - private readonly HashSet referencedInputs = new HashSet(EqualityComparer.Default); - - private readonly ResourceExpression input; - - private readonly ResourceSetExpression inputSet; - - private readonly ParameterExpression inputParameter; - - #endregion Private fields. - - private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam) - { - this.input = resource; - this.inputSet = resource as ResourceSetExpression; - this.inputParameter = setReferenceParam; - } - - internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List referencedInputs) - { - Debug.Assert(e != null, "Expression cannot be null"); - Debug.Assert(currentInput != null, "A current input resource set is required"); - Debug.Assert(inputParameter != null, "The input lambda parameter is required"); - Debug.Assert(referencedInputs != null, "The referenced inputs list is required"); - - InputBinder binder = new InputBinder(currentInput, inputParameter); - Expression result = binder.Visit(e); - referencedInputs.AddRange(binder.referencedInputs); - return result; - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - if (this.inputSet == null || - !this.inputSet.HasTransparentScope) - { - return base.VisitMemberAccess(m); - } - - ParameterExpression innerParamRef = null; - Stack nestedAccesses = new Stack(); - MemberExpression memberRef = m; - while (memberRef != null && - memberRef.Member.MemberType == MemberTypes.Property && - memberRef.Expression != null) - { - nestedAccesses.Push((PropertyInfo)memberRef.Member); - - if (memberRef.Expression.NodeType == ExpressionType.Parameter) - { - innerParamRef = (ParameterExpression)memberRef.Expression; - } - - memberRef = memberRef.Expression as MemberExpression; - } - - if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0) - { - return m; - } - - ResourceExpression target = this.input; - ResourceSetExpression targetSet = this.inputSet; - bool transparentScopeTraversed = false; - - while (nestedAccesses.Count > 0) - { - if (targetSet == null || !targetSet.HasTransparentScope) - { - break; - } - - PropertyInfo currentProp = nestedAccesses.Peek(); - - if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal)) - { - target = targetSet; - nestedAccesses.Pop(); - transparentScopeTraversed = true; - continue; - } - - Expression source; - if (!targetSet.TransparentScope.SourceAccessors.TryGetValue(currentProp.Name, out source)) - { - break; - } - - transparentScopeTraversed = true; - nestedAccesses.Pop(); - Debug.Assert(source != null, "source != null -- otherwise ResourceBinder created an accessor to nowhere"); - InputReferenceExpression sourceReference = source as InputReferenceExpression; - if (sourceReference == null) - { - targetSet = source as ResourceSetExpression; - if (targetSet == null || !targetSet.HasTransparentScope) - { - target = (ResourceExpression)source; - } - } - else - { - targetSet = sourceReference.Target as ResourceSetExpression; - target = targetSet; - } - } - - if (!transparentScopeTraversed) - { - return m; - } - - Expression result = this.CreateReference(target); - while (nestedAccesses.Count > 0) - { - result = Expression.Property(result, nestedAccesses.Pop()); - } - - return result; - } - - internal override Expression VisitParameter(ParameterExpression p) - { - if ((this.inputSet == null || !this.inputSet.HasTransparentScope) && - p == this.inputParameter) - { - return this.CreateReference(this.input); - } - else - { - return base.VisitParameter(p); - } - } - - private Expression CreateReference(ResourceExpression resource) - { - this.referencedInputs.Add(resource); - return resource.CreateReference(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputReferenceExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputReferenceExpression.cs deleted file mode 100644 index 5f07b27c5b822..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/InputReferenceExpression.cs +++ /dev/null @@ -1,50 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System.Diagnostics; - using System.Linq.Expressions; - - [DebuggerDisplay("InputReferenceExpression -> {Type}")] - internal sealed class InputReferenceExpression : Expression - { - private ResourceExpression target; - -#pragma warning disable 618 - internal InputReferenceExpression(ResourceExpression target) - : base((ExpressionType)ResourceExpressionType.InputReference, target.ResourceType) - { - Debug.Assert(target != null, "Target resource set cannot be null"); - this.target = target; - } -#pragma warning restore 618 - - internal ResourceExpression Target - { - get { return this.target; } - } - - internal void OverrideTarget(ResourceSetExpression newTarget) - { - Debug.Assert(newTarget != null, "Resource set cannot be null"); - Debug.Assert(newTarget.ResourceType.Equals(this.Type), "Cannot reference a resource set with a different resource type"); - - this.target = newTarget; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/MemberAssignmentAnalysis.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/MemberAssignmentAnalysis.cs deleted file mode 100644 index e9414a1dd5c23..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/MemberAssignmentAnalysis.cs +++ /dev/null @@ -1,283 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - - #endregion Namespaces. - - internal class MemberAssignmentAnalysis : ALinqExpressionVisitor - { - #region Fields. - - internal static readonly Expression[] EmptyExpressionArray = new Expression[0]; - - private readonly Expression entity; - - private Exception incompatibleAssignmentsException; - - private bool multiplePathsFound; - - private List pathFromEntity; - - #endregion Fields. - - #region Constructor. - - private MemberAssignmentAnalysis(Expression entity) - { - Debug.Assert(entity != null, "entity != null"); - - this.entity = entity; - this.pathFromEntity = new List(); - } - - #endregion Constructor. - - #region Properties. - - internal Exception IncompatibleAssignmentsException - { - get { return this.incompatibleAssignmentsException; } - } - - internal bool MultiplePathsFound - { - get { return this.multiplePathsFound; } - } - - #endregion Properites. - - #region Methods. - - internal static MemberAssignmentAnalysis Analyze(Expression entityInScope, Expression assignmentExpression) - { - Debug.Assert(entityInScope != null, "entityInScope != null"); - Debug.Assert(assignmentExpression != null, "assignmentExpression != null"); - - MemberAssignmentAnalysis result = new MemberAssignmentAnalysis(entityInScope); - result.Visit(assignmentExpression); - return result; - } - - internal Exception CheckCompatibleAssignments(Type targetType, ref MemberAssignmentAnalysis previous) - { - if (previous == null) - { - previous = this; - return null; - } - - Expression[] previousExpressions = previous.GetExpressionsToTargetEntity(); - Expression[] candidateExpressions = this.GetExpressionsToTargetEntity(); - return CheckCompatibleAssignments(targetType, previousExpressions, candidateExpressions); - } - - internal override Expression Visit(Expression expression) - { - if (this.multiplePathsFound || this.incompatibleAssignmentsException != null) - { - return expression; - } - - return base.Visit(expression); - } - - internal override Expression VisitConditional(ConditionalExpression c) - { - Expression result; - - var nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.entity, c); - if (nullCheck.Match) - { - this.Visit(nullCheck.AssignExpression); - result = c; - } - else - { - result = base.VisitConditional(c); - } - - return result; - } - - internal override Expression VisitParameter(ParameterExpression p) - { - if (p == this.entity) - { - if (this.pathFromEntity.Count != 0) - { - this.multiplePathsFound = true; - } - else - { - this.pathFromEntity.Add(p); - } - } - - return p; - } - - internal override Expression VisitMemberInit(MemberInitExpression init) - { - Expression result = init; - MemberAssignmentAnalysis previousNested = null; - foreach (var binding in init.Bindings) - { - MemberAssignment assignment = binding as MemberAssignment; - if (assignment == null) - { - continue; - } - - MemberAssignmentAnalysis nested = MemberAssignmentAnalysis.Analyze(this.entity, assignment.Expression); - if (nested.MultiplePathsFound) - { - this.multiplePathsFound = true; - break; - } - - Exception incompatibleException = nested.CheckCompatibleAssignments(init.Type, ref previousNested); - if (incompatibleException != null) - { - this.incompatibleAssignmentsException = incompatibleException; - break; - } - - if (this.pathFromEntity.Count == 0) - { - this.pathFromEntity.AddRange(nested.GetExpressionsToTargetEntity()); - } - } - - return result; - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - Expression result = base.VisitMemberAccess(m); - if (this.pathFromEntity.Contains(m.Expression)) - { - this.pathFromEntity.Add(m); - } - - return result; - } - - internal override Expression VisitMethodCall(MethodCallExpression call) - { - if (ReflectionUtil.IsSequenceMethod(call.Method, SequenceMethod.Select)) - { - this.Visit(call.Arguments[0]); - return call; - } - - return base.VisitMethodCall(call); - } - - internal Expression[] GetExpressionsBeyondTargetEntity() - { - Debug.Assert(!this.multiplePathsFound, "this.multiplePathsFound -- otherwise GetExpressionsToTargetEntity won't return reliable (consistent) results"); - - if (this.pathFromEntity.Count <= 1) - { - return EmptyExpressionArray; - } - - Expression[] result = new Expression[1]; - result[0] = this.pathFromEntity[this.pathFromEntity.Count - 1]; - return result; - } - - internal Expression[] GetExpressionsToTargetEntity() - { - Debug.Assert(!this.multiplePathsFound, "this.multiplePathsFound -- otherwise GetExpressionsToTargetEntity won't return reliable (consistent) results"); - - if (this.pathFromEntity.Count <= 1) - { - return EmptyExpressionArray; - } - - Expression[] result = new Expression[this.pathFromEntity.Count - 1]; - for (int i = 0; i < result.Length; i++) - { - result[i] = this.pathFromEntity[i]; - } - - return result; - } - - private static Exception CheckCompatibleAssignments(Type targetType, Expression[] previous, Expression[] candidate) - { - Debug.Assert(targetType != null, "targetType != null"); - Debug.Assert(previous != null, "previous != null"); - Debug.Assert(candidate != null, "candidate != null"); - - if (previous.Length != candidate.Length) - { - throw CheckCompatibleAssignmentsFail(targetType, previous, candidate); - } - - for (int i = 0; i < previous.Length; i++) - { - Expression p = previous[i]; - Expression c = candidate[i]; - if (p.NodeType != c.NodeType) - { - throw CheckCompatibleAssignmentsFail(targetType, previous, candidate); - } - - if (p == c) - { - continue; - } - - if (p.NodeType != ExpressionType.MemberAccess) - { - return CheckCompatibleAssignmentsFail(targetType, previous, candidate); - } - - if (((MemberExpression)p).Member.Name != ((MemberExpression)c).Member.Name) - { - return CheckCompatibleAssignmentsFail(targetType, previous, candidate); - } - } - - return null; - } - - private static Exception CheckCompatibleAssignmentsFail(Type targetType, Expression[] previous, Expression[] candidate) - { - Debug.Assert(targetType != null, "targetType != null"); - Debug.Assert(previous != null, "previous != null"); - Debug.Assert(candidate != null, "candidate != null"); - - return new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqProjectionMemberAssignmentMismatch, targetType.FullName, previous.LastOrDefault(), candidate.LastOrDefault())); - } - - #endregion Methods. - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/NavigationPropertySingletonExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/NavigationPropertySingletonExpression.cs deleted file mode 100644 index 4b3ab8c30fbc3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/NavigationPropertySingletonExpression.cs +++ /dev/null @@ -1,92 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Private fields. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Linq.Expressions; - - #endregion Private fields. - - internal class NavigationPropertySingletonExpression : ResourceExpression - { - #region Private fields. - - private readonly Expression memberExpression; - - private readonly Type resourceType; - - #endregion Private fields. - - internal NavigationPropertySingletonExpression(Type type, Expression source, Expression memberExpression, Type resourceType, List expandPaths, CountOption countOption, Dictionary customQueryOptions, ProjectionQueryOptionExpression projection) - : base(source, (ExpressionType)ResourceExpressionType.ResourceNavigationPropertySingleton, type, expandPaths, countOption, customQueryOptions, projection) - { - Debug.Assert(memberExpression != null, "memberExpression != null"); - Debug.Assert(resourceType != null, "resourceType != null"); - - this.memberExpression = memberExpression; - this.resourceType = resourceType; - } - - internal MemberExpression MemberExpression - { - get - { - return (MemberExpression)this.memberExpression; - } - } - - internal override Type ResourceType - { - get { return this.resourceType; } - } - - internal override bool IsSingleton - { - get { return true; } - } - - internal override bool HasQueryOptions - { - get - { - return this.ExpandPaths.Count > 0 || - this.CountOption == CountOption.InlineAll || - this.CustomQueryOptions.Count > 0 || - this.Projection != null; - } - } - - internal override ResourceExpression CreateCloneWithNewType(Type type) - { - return new NavigationPropertySingletonExpression( - type, - this.Source, - this.MemberExpression, - TypeSystem.GetElementType(type), - this.ExpandPaths.ToList(), - this.CountOption, - this.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), - this.Projection); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/OperationContextQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/OperationContextQueryOptionExpression.cs deleted file mode 100644 index b18c89cc44078..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/OperationContextQueryOptionExpression.cs +++ /dev/null @@ -1,43 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq.Expressions; - - [DebuggerDisplay("OperationContextQueryOptionExpression {operationContext}")] - internal class OperationContextQueryOptionExpression : QueryOptionExpression - { - private ConstantExpression operationContext; - - internal OperationContextQueryOptionExpression(Type type, ConstantExpression operationContext) - : base((ExpressionType)ResourceExpressionType.OperationContext, type) - { - this.operationContext = operationContext; - } - - internal ConstantExpression OperationContext - { - get - { - return this.operationContext; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/PathBox.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/PathBox.cs deleted file mode 100644 index 0eecf00027087..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/PathBox.cs +++ /dev/null @@ -1,163 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - using System.Text; - - #endregion Namespaces. - - internal class PathBox - { - #region Private fields. - - private const char EntireEntityMarker = UriHelper.ASTERISK; - - private readonly List projectionPaths = new List(); - - private readonly List expandPaths = new List(); - - private readonly Stack parameterExpressions = new Stack(); - - private readonly Dictionary basePaths = new Dictionary(ReferenceEqualityComparer.Instance); - - #endregion Private fields. - - internal PathBox() - { - this.projectionPaths.Add(new StringBuilder()); - } - - internal IEnumerable ProjectionPaths - { - get - { - return this.projectionPaths.Where(s => s.Length > 0).Select(s => s.ToString()).Distinct(); - } - } - - internal IEnumerable ExpandPaths - { - get - { - return this.expandPaths.Where(s => s.Length > 0).Select(s => s.ToString()).Distinct(); - } - } - - internal void PushParamExpression(ParameterExpression pe) - { - StringBuilder basePath = this.projectionPaths.Last(); - this.basePaths.Add(pe, basePath.ToString()); - this.projectionPaths.Remove(basePath); - this.parameterExpressions.Push(pe); - } - - internal void PopParamExpression() - { - this.parameterExpressions.Pop(); - } - - internal ParameterExpression ParamExpressionInScope - { - get - { - // Debug.Assert(parameterExpressions.Count > 0); - return this.parameterExpressions.Peek(); - } - } - - internal void StartNewPath() - { - Debug.Assert(this.ParamExpressionInScope != null, "this.ParamExpressionInScope != null -- should not be starting new path with no lambda parameter in scope."); - - StringBuilder sb = new StringBuilder(this.basePaths[this.ParamExpressionInScope]); - RemoveEntireEntityMarkerIfPresent(sb); - this.expandPaths.Add(new StringBuilder(sb.ToString())); - AddEntireEntityMarker(sb); - this.projectionPaths.Add(sb); - } - - internal void AppendToPath(PropertyInfo pi) - { - Debug.Assert(pi != null, "pi != null"); - - StringBuilder sb; - Type t = TypeSystem.GetElementType(pi.PropertyType); - - if (CommonUtil.IsClientType(t)) - { - sb = this.expandPaths.Last(); - - // Debug.Assert(sb != null); - if (sb.Length > 0) - { - sb.Append(UriHelper.FORWARDSLASH); - } - - sb.Append(pi.Name); - } - - sb = this.projectionPaths.Last(); - Debug.Assert(sb != null, "sb != null -- we are always building paths in the context of a parameter"); - - RemoveEntireEntityMarkerIfPresent(sb); - - if (sb.Length > 0) - { - sb.Append(UriHelper.FORWARDSLASH); - } - - sb.Append(pi.Name); - - if (CommonUtil.IsClientType(t)) - { - AddEntireEntityMarker(sb); - } - } - - private static void RemoveEntireEntityMarkerIfPresent(StringBuilder sb) - { - if (sb.Length > 0 && sb[sb.Length - 1] == EntireEntityMarker) - { - sb.Remove(sb.Length - 1, 1); - } - - if (sb.Length > 0 && sb[sb.Length - 1] == UriHelper.FORWARDSLASH) - { - sb.Remove(sb.Length - 1, 1); - } - } - - private static void AddEntireEntityMarker(StringBuilder sb) - { - if (sb.Length > 0) - { - sb.Append(UriHelper.FORWARDSLASH); - } - - sb.Append(EntireEntityMarker); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionAnalyzer.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionAnalyzer.cs deleted file mode 100644 index b23e524eaecb4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionAnalyzer.cs +++ /dev/null @@ -1,580 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - #endregion Namespaces. - - internal static class ProjectionAnalyzer - { - #region Internal methods. - - internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers) - { - Debug.Assert(le != null, "le != null"); - - if (le.Body.NodeType == ExpressionType.Constant) - { - if (CommonUtil.IsClientType(le.Body.Type)) - { - throw new NotSupportedException(SR.ALinqCannotCreateConstantEntity); - } - - re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List()); - return true; - } - - if (le.Body.NodeType == ExpressionType.Call) - { - MethodCallExpression mce = le.Body as MethodCallExpression; - if (mce.Method == ReflectionUtil.ProjectMethodInfo.MakeGenericMethod(le.Body.Type)) - { - ConstantExpression paths = mce.Arguments[1] as ConstantExpression; - - re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, ProjectionQueryOptionExpression.DefaultLambda, new List((string[])paths.Value)); - return true; - } - } - - if (le.Body.NodeType == ExpressionType.MemberInit || le.Body.NodeType == ExpressionType.New) - { - AnalyzeResourceExpression(le, re); - return true; - } - - if (matchMembers) - { - Expression withoutConverts = SkipConverts(le.Body); - if (withoutConverts.NodeType == ExpressionType.MemberAccess) - { - AnalyzeResourceExpression(le, re); - return true; - } - } - - return false; - } - - internal static void Analyze(LambdaExpression e, PathBox pb) - { - bool knownEntityType = CommonUtil.IsClientType(e.Body.Type); - pb.PushParamExpression(e.Parameters.Last()); - - if (!knownEntityType) - { - NonEntityProjectionAnalyzer.Analyze(e.Body, pb); - } - else - { - switch (e.Body.NodeType) - { - case ExpressionType.MemberInit: - EntityProjectionAnalyzer.Analyze((MemberInitExpression)e.Body, pb); - break; - case ExpressionType.New: - throw new NotSupportedException(SR.ALinqCannotConstructKnownEntityTypes); - case ExpressionType.Constant: - throw new NotSupportedException(SR.ALinqCannotCreateConstantEntity); - default: - NonEntityProjectionAnalyzer.Analyze(e.Body, pb); - break; - } - } - - pb.PopParamExpression(); - } - - internal static bool IsMethodCallAllowedEntitySequence(MethodCallExpression call) - { - Debug.Assert(call != null, "call != null"); - return - ReflectionUtil.IsSequenceMethod(call.Method, SequenceMethod.ToList) || - ReflectionUtil.IsSequenceMethod(call.Method, SequenceMethod.Select); - } - - internal static void CheckChainedSequence(MethodCallExpression call, Type type) - { - if (ReflectionUtil.IsSequenceMethod(call.Method, SequenceMethod.Select)) - { - MethodCallExpression insideCall = ResourceBinder.StripTo(call.Arguments[0]); - if (insideCall != null && ReflectionUtil.IsSequenceMethod(insideCall.Method, SequenceMethod.Select)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, type, call.ToString())); - } - } - } - - #endregion Internal methods. - - #region Private methods. - - private static void Analyze(MemberInitExpression mie, PathBox pb) - { - Debug.Assert(mie != null, "mie != null"); - Debug.Assert(pb != null, "pb != null"); - - bool knownEntityType = CommonUtil.IsClientType(mie.Type); - if (knownEntityType) - { - EntityProjectionAnalyzer.Analyze(mie, pb); - } - else - { - NonEntityProjectionAnalyzer.Analyze(mie, pb); - } - } - - private static void AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource) - { - PathBox pb = new PathBox(); - ProjectionAnalyzer.Analyze(lambda, pb); - resource.Projection = new ProjectionQueryOptionExpression(lambda.Body.Type, lambda, pb.ProjectionPaths.ToList()); - resource.ExpandPaths = pb.ExpandPaths.Union(resource.ExpandPaths, StringComparer.Ordinal).ToList(); - } - - private static Expression SkipConverts(Expression expression) - { - Expression result = expression; - while (result.NodeType == ExpressionType.Convert || result.NodeType == ExpressionType.ConvertChecked) - { - result = ((UnaryExpression)result).Operand; - } - - return result; - } - - #endregion Private methods. - - #region Inner types. - - private class EntityProjectionAnalyzer : ALinqExpressionVisitor - { - #region Private fields. - - private readonly PathBox box; - - private readonly Type type; - - #endregion Private fields. - - private EntityProjectionAnalyzer(PathBox pb, Type type) - { - Debug.Assert(pb != null, "pb != null"); - Debug.Assert(type != null, "type != null"); - - this.box = pb; - this.type = type; - } - - internal static void Analyze(MemberInitExpression mie, PathBox pb) - { - Debug.Assert(mie != null, "mie != null"); - - var epa = new EntityProjectionAnalyzer(pb, mie.Type); - - MemberAssignmentAnalysis targetEntityPath = null; - foreach (MemberBinding mb in mie.Bindings) - { - MemberAssignment ma = mb as MemberAssignment; - epa.Visit(ma.Expression); - if (ma != null) - { - var analysis = MemberAssignmentAnalysis.Analyze(pb.ParamExpressionInScope, ma.Expression); - if (analysis.IncompatibleAssignmentsException != null) - { - throw analysis.IncompatibleAssignmentsException; - } - - Type targetType = GetMemberType(ma.Member); - Expression[] lastExpressions = analysis.GetExpressionsBeyondTargetEntity(); - if (lastExpressions.Length == 0) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, targetType, ma.Expression)); - } - - MemberExpression lastExpression = lastExpressions[lastExpressions.Length - 1] as MemberExpression; - Debug.Assert( - !analysis.MultiplePathsFound, - "!analysis.MultiplePathsFound -- the initilizer has been visited, and cannot be empty, and expressions that can combine paths should have thrown exception during initializer analysis"); - Debug.Assert( - lastExpression != null, - "lastExpression != null -- the initilizer has been visited, and cannot be empty, and the only expressions that are allowed can be formed off the parameter, so this is always correlatd"); - if (lastExpression != null && (lastExpression.Member.Name != ma.Member.Name)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqPropertyNamesMustMatchInProjections, lastExpression.Member.Name, ma.Member.Name)); - } - - analysis.CheckCompatibleAssignments(mie.Type, ref targetEntityPath); - - bool targetIsEntity = CommonUtil.IsClientType(targetType); - bool sourceIsEntity = CommonUtil.IsClientType(lastExpression.Type); - if (sourceIsEntity && !targetIsEntity) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, targetType, ma.Expression)); - } - } - } - } - - internal override Expression VisitUnary(UnaryExpression u) - { - Debug.Assert(u != null, "u != null"); - - if (ResourceBinder.PatternRules.MatchConvertToAssignable(u)) - { - return base.VisitUnary(u); - } - - if ((u.NodeType == ExpressionType.Convert) || (u.NodeType == ExpressionType.ConvertChecked)) - { - Type sourceType = Nullable.GetUnderlyingType(u.Operand.Type) ?? u.Operand.Type; - Type targetType = Nullable.GetUnderlyingType(u.Type) ?? u.Type; - - if (ClientConvert.IsKnownType(sourceType) && ClientConvert.IsKnownType(targetType)) - { - return base.Visit(u.Operand); - } - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, u.ToString())); - } - - internal override Expression VisitBinary(BinaryExpression b) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, b.ToString())); - } - - internal override Expression VisitTypeIs(TypeBinaryExpression b) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, b.ToString())); - } - - internal override Expression VisitConditional(ConditionalExpression c) - { - var nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.box.ParamExpressionInScope, c); - if (nullCheck.Match) - { - this.Visit(nullCheck.AssignExpression); - return c; - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, c.ToString())); - } - - internal override Expression VisitConstant(ConstantExpression c) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, c.ToString())); - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - Debug.Assert(m != null, "m != null"); - - if (!CommonUtil.IsClientType(m.Expression.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, m.ToString())); - } - - PropertyInfo pi = null; - if (ResourceBinder.PatternRules.MatchNonPrivateReadableProperty(m, out pi)) - { - Expression e = base.VisitMemberAccess(m); - this.box.AppendToPath(pi); - return e; - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, m.ToString())); - } - - internal override Expression VisitMethodCall(MethodCallExpression m) - { - /* - if ((m.Object != null && ProjectionAnalyzer.IsDisallowedExpressionForMethodCall(m.Object)) - || m.Arguments.Any(a => ProjectionAnalyzer.IsDisallowedExpressionForMethodCall(a))) - { - throw new NotSupportedException(string.Format(SR.ALinqExpressionNotSupportedInProjection, this.type, m.ToString())); - } - */ - - if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m)) - { - ProjectionAnalyzer.CheckChainedSequence(m, this.type); - - return base.VisitMethodCall(m); - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, m.ToString())); - } - - internal override Expression VisitInvocation(InvocationExpression iv) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, iv.ToString())); - } - - internal override Expression VisitLambda(LambdaExpression lambda) - { - ProjectionAnalyzer.Analyze(lambda, this.box); - return lambda; - } - - internal override Expression VisitListInit(ListInitExpression init) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, init.ToString())); - } - - internal override Expression VisitNewArray(NewArrayExpression na) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, na.ToString())); - } - - internal override Expression VisitMemberInit(MemberInitExpression init) - { - ProjectionAnalyzer.Analyze(init, this.box); - return init; - } - - internal override NewExpression VisitNew(NewExpression nex) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, nex.ToString())); - } - - internal override Expression VisitParameter(ParameterExpression p) - { - if (p != this.box.ParamExpressionInScope) - { - throw new NotSupportedException(SR.ALinqCanOnlyProjectTheLeaf); - } - - this.box.StartNewPath(); - return p; - } - - private static Type GetMemberType(MemberInfo member) - { - Debug.Assert(member != null, "member != null"); - - PropertyInfo propertyInfo = member as PropertyInfo; - if (propertyInfo != null) - { - return propertyInfo.PropertyType; - } - - FieldInfo fieldInfo = member as FieldInfo; - Debug.Assert(fieldInfo != null, "fieldInfo != null -- otherwise Expression.Member factory should have thrown an argument exception"); - return fieldInfo.FieldType; - } - } - - private class NonEntityProjectionAnalyzer : DataServiceALinqExpressionVisitor - { - private PathBox box; - - private Type type; - - private NonEntityProjectionAnalyzer(PathBox pb, Type type) - { - this.box = pb; - this.type = type; - } - - internal static void Analyze(Expression e, PathBox pb) - { - var nepa = new NonEntityProjectionAnalyzer(pb, e.Type); - - MemberInitExpression mie = e as MemberInitExpression; - - if (mie != null) - { - foreach (MemberBinding mb in mie.Bindings) - { - MemberAssignment ma = mb as MemberAssignment; - if (ma != null) - { - nepa.Visit(ma.Expression); - } - } - } - else - { - nepa.Visit(e); - } - } - - internal override Expression VisitUnary(UnaryExpression u) - { - Debug.Assert(u != null, "u != null"); - - if (!ResourceBinder.PatternRules.MatchConvertToAssignable(u)) - { - if (CommonUtil.IsClientType(u.Operand.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, u.ToString())); - } - } - - return base.VisitUnary(u); - } - - internal override Expression VisitBinary(BinaryExpression b) - { - if (CommonUtil.IsClientType(b.Left.Type) || CommonUtil.IsClientType(b.Right.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, b.ToString())); - } - - return base.VisitBinary(b); - } - - internal override Expression VisitTypeIs(TypeBinaryExpression b) - { - if (CommonUtil.IsClientType(b.Expression.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, b.ToString())); - } - - return base.VisitTypeIs(b); - } - - internal override Expression VisitConditional(ConditionalExpression c) - { - var nullCheck = ResourceBinder.PatternRules.MatchNullCheck(this.box.ParamExpressionInScope, c); - if (nullCheck.Match) - { - this.Visit(nullCheck.AssignExpression); - return c; - } - - if (CommonUtil.IsClientType(c.Test.Type) || CommonUtil.IsClientType(c.IfTrue.Type) || CommonUtil.IsClientType(c.IfFalse.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, c.ToString())); - } - - return base.VisitConditional(c); - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - Debug.Assert(m != null, "m != null"); - - if (ClientConvert.IsKnownNullableType(m.Expression.Type)) - { - return base.VisitMemberAccess(m); - } - - if (!CommonUtil.IsClientType(m.Expression.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, m.ToString())); - } - - PropertyInfo pi = null; - if (ResourceBinder.PatternRules.MatchNonPrivateReadableProperty(m, out pi)) - { - Expression e = base.VisitMemberAccess(m); - this.box.AppendToPath(pi); - return e; - } - - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, m.ToString())); - } - - internal override Expression VisitMethodCall(MethodCallExpression m) - { - if (ProjectionAnalyzer.IsMethodCallAllowedEntitySequence(m)) - { - ProjectionAnalyzer.CheckChainedSequence(m, this.type); - - return base.VisitMethodCall(m); - } - - if ((m.Object != null ? CommonUtil.IsClientType(m.Object.Type) : false) - || m.Arguments.Any(a => CommonUtil.IsClientType(a.Type))) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, m.ToString())); - } - - return base.VisitMethodCall(m); - } - - internal override Expression VisitInvocation(InvocationExpression iv) - { - if (CommonUtil.IsClientType(iv.Expression.Type) - || iv.Arguments.Any(a => CommonUtil.IsClientType(a.Type))) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, iv.ToString())); - } - - return base.VisitInvocation(iv); - } - - internal override Expression VisitLambda(LambdaExpression lambda) - { - ProjectionAnalyzer.Analyze(lambda, this.box); - return lambda; - } - - internal override Expression VisitMemberInit(MemberInitExpression init) - { - ProjectionAnalyzer.Analyze(init, this.box); - return init; - } - - internal override NewExpression VisitNew(NewExpression nex) - { - if (CommonUtil.IsClientType(nex.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, nex.ToString())); - } - - return base.VisitNew(nex); - } - - internal override Expression VisitParameter(ParameterExpression p) - { - if (p != this.box.ParamExpressionInScope) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, p.ToString())); - } - - this.box.StartNewPath(); - return p; - } - - internal override Expression VisitConstant(ConstantExpression c) - { - if (CommonUtil.IsClientType(c.Type)) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, c.ToString())); - } - - return base.VisitConstant(c); - } - } - - #endregion Inner types. - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionQueryOptionExpression.cs deleted file mode 100644 index 972774dd1e8a1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionQueryOptionExpression.cs +++ /dev/null @@ -1,72 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq.Expressions; - - #endregion Namespaces. - - internal class ProjectionQueryOptionExpression : QueryOptionExpression - { - #region Private fields. - - private readonly LambdaExpression lambda; - - private readonly List paths; - - #endregion Private fields. - - internal static readonly LambdaExpression DefaultLambda = Expression.Lambda(Expression.Constant(0), null); - - internal ProjectionQueryOptionExpression(Type type, LambdaExpression lambda, List paths) - : base((ExpressionType)ResourceExpressionType.ProjectionQueryOption, type) - { - Debug.Assert(type != null, "type != null"); - Debug.Assert(lambda != null, "lambda != null"); - Debug.Assert(paths != null, "paths != null"); - - this.lambda = lambda; - this.paths = paths; - } - - #region Internal properties. - - internal LambdaExpression Selector - { - get - { - return this.lambda; - } - } - - internal List Paths - { - get - { - return this.paths; - } - } - - #endregion Internal properties. - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionRewriter.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionRewriter.cs deleted file mode 100644 index a336d05d0a507..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ProjectionRewriter.cs +++ /dev/null @@ -1,108 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Diagnostics; - using System.Linq; - using System.Linq.Expressions; - - #endregion Namespaces. - - internal class ProjectionRewriter : ALinqExpressionVisitor - { - #region Private fields. - - private readonly ParameterExpression newLambdaParameter; - - private ParameterExpression oldLambdaParameter; - - private bool sucessfulRebind; - - #endregion Private fields. - - private ProjectionRewriter(Type proposedParameterType) - { - Debug.Assert(proposedParameterType != null, "proposedParameterType != null"); - this.newLambdaParameter = Expression.Parameter(proposedParameterType, "it"); - } - - #region Internal methods. - - internal static LambdaExpression TryToRewrite(LambdaExpression le, Type proposedParameterType) - { - LambdaExpression result; - if (!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) || - /* TODO Fix ME ! CommonUtil.IsClientType(le.Parameters[0].Type) || */ - !le.Parameters[0].Type.GetProperties().Any(p => p.PropertyType == proposedParameterType)) - { - result = le; - } - else - { - ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType); - result = rewriter.Rebind(le); - } - - return result; - } - - internal LambdaExpression Rebind(LambdaExpression lambda) - { - this.sucessfulRebind = true; - this.oldLambdaParameter = lambda.Parameters[0]; - - Expression body = this.Visit(lambda.Body); - if (this.sucessfulRebind) - { - Type delegateType = typeof(Func<,>).MakeGenericType(new Type[] { this.newLambdaParameter.Type, lambda.Body.Type }); -#if ASTORIA_LIGHT - return ExpressionHelpers.CreateLambda(delegateType, body, new ParameterExpression[] { this.newLambdaParameter }); -#else - return Expression.Lambda(delegateType, body, new ParameterExpression[] { this.newLambdaParameter }); -#endif - } - else - { - throw new NotSupportedException(SR.ALinqCanOnlyProjectTheLeaf); - } - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - if (m.Expression == this.oldLambdaParameter) - { - if (m.Type == this.newLambdaParameter.Type) - { - return this.newLambdaParameter; - } - else - { - this.sucessfulRebind = false; - } - } - - return base.VisitMemberAccess(m); - } - - #endregion Internal methods. - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/QueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/QueryOptionExpression.cs deleted file mode 100644 index 103f71ee5aab7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/QueryOptionExpression.cs +++ /dev/null @@ -1,39 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq.Expressions; - - internal abstract class QueryOptionExpression : Expression - { -#pragma warning disable 618 - internal QueryOptionExpression(ExpressionType nodeType, Type type) : base(nodeType, type) - { - } -#pragma warning restore 618 - - internal virtual QueryOptionExpression ComposeMultipleSpecification(QueryOptionExpression previous) - { - Debug.Assert(previous != null, "other != null"); - Debug.Assert(previous.GetType() == this.GetType(), "other.GetType == this.GetType() -- otherwise it's not the same specification"); - return this; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReferenceEqualityComparer.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReferenceEqualityComparer.cs deleted file mode 100644 index f6c9dc6513435..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReferenceEqualityComparer.cs +++ /dev/null @@ -1,137 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System.Collections; - using System.Collections.Generic; - using System.Diagnostics; - - #endregion Namespaces. - - internal class ReferenceEqualityComparer : IEqualityComparer - { - #region Private fields. - -#if NON_GENERIC_AVAILABLE - private static ReferenceEqualityComparer nonGenericInstance; -#endif - - #endregion Private fields. - - #region Constructors. - - protected ReferenceEqualityComparer() - { - } - - #endregion Constructors. - - #region Properties. - - bool IEqualityComparer.Equals(object x, object y) - { - return object.ReferenceEquals(x, y); - } - - int IEqualityComparer.GetHashCode(object obj) - { - if (obj == null) - { - return 0; - } - - return obj.GetHashCode(); - } - -#if NON_GENERIC_AVAILABLE - internal ReferenceEqualityComparer NonGenericInstance - { - get - { - if (nonGenericInstance == null) - { - ReferenceEqualityComparer comparer = new ReferenceEqualityComparer(); - System.Threading.Interlocked.CompareExchange(ref nonGenericInstance, comparer, null); - } - - return nonGenericInstance; - } - } -#endif - - #endregion Properties. - } - - internal sealed class ReferenceEqualityComparer : ReferenceEqualityComparer, IEqualityComparer - { - #region Private fields. - - private static ReferenceEqualityComparer instance; - - #endregion Private fields. - - #region Constructors. - - private ReferenceEqualityComparer() - : base() - { - } - - #endregion Constructors. - - #region Properties. - - internal static ReferenceEqualityComparer Instance - { - get - { - if (instance == null) - { - Debug.Assert(!typeof(T).IsValueType, "!typeof(T).IsValueType -- can't use reference equality in a meaningful way with value types"); - ReferenceEqualityComparer newInstance = new ReferenceEqualityComparer(); - System.Threading.Interlocked.CompareExchange(ref instance, newInstance, null); - } - - return instance; - } - } - - #endregion Properties. - - #region Methods. - - public bool Equals(T x, T y) - { - return object.ReferenceEquals(x, y); - } - - public int GetHashCode(T obj) - { - if (obj == null) - { - return 0; - } - - return obj.GetHashCode(); - } - - #endregion Methods. - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReflectionUtil.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReflectionUtil.cs deleted file mode 100644 index 25f06070bd04f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ReflectionUtil.cs +++ /dev/null @@ -1,675 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Reflection; - using System.Text; - - #endregion Namespaces. - - internal static class ReflectionUtil - { - #region Static information on sequence methods - private static readonly Dictionary StaticMethodMap; - - private static readonly Dictionary StaticInverseMap; - - internal static MethodInfo DictionaryGetItemMethodInfo { get; set; } - - internal static MethodInfo TableQueryProviderReturnSingletonMethodInfo { get; set; } - - internal static MethodInfo ProjectMethodInfo { get; set; } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Performance")] - static ReflectionUtil() - { - Dictionary map = new Dictionary(EqualityComparer.Default); - - map.Add(@"Sum(IQueryable`1, Expression`1>)->Double", SequenceMethod.SumDoubleSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.SumNullableDoubleSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>)->Decimal", SequenceMethod.SumDecimalSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.SumNullableDecimalSelector); - map.Add(@"Average(IQueryable`1, Expression`1>)->Double", SequenceMethod.AverageIntSelector); - map.Add(@"Average(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.AverageNullableIntSelector); - map.Add(@"Average(IQueryable`1, Expression`1>)->Single", SequenceMethod.AverageSingleSelector); - map.Add(@"Average(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.AverageNullableSingleSelector); - map.Add(@"Average(IQueryable`1, Expression`1>)->Double", SequenceMethod.AverageLongSelector); - map.Add(@"Average(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.AverageNullableLongSelector); - map.Add(@"Average(IQueryable`1, Expression`1>)->Double", SequenceMethod.AverageDoubleSelector); - map.Add(@"Average(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.AverageNullableDoubleSelector); - map.Add(@"Average(IQueryable`1, Expression`1>)->Decimal", SequenceMethod.AverageDecimalSelector); - map.Add(@"Average(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.AverageNullableDecimalSelector); - map.Add(@"Aggregate(IQueryable`1, Expression`1>)->T0", SequenceMethod.Aggregate); - map.Add(@"Aggregate(IQueryable`1, T1, Expression`1>)->T1", SequenceMethod.AggregateSeed); - map.Add(@"Aggregate(IQueryable`1, T1, Expression`1>, Expression`1>)->T2", SequenceMethod.AggregateSeedSelector); - map.Add(@"AsQueryable(IEnumerable`1)->IQueryable`1", SequenceMethod.AsQueryableGeneric); - map.Add(@"Where(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.Where); - map.Add(@"Where(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.WhereOrdinal); - map.Add(@"OfType(IQueryable)->IQueryable`1", SequenceMethod.OfType); - map.Add(@"Cast(IQueryable)->IQueryable`1", SequenceMethod.Cast); - map.Add(@"Select(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.Select); - map.Add(@"Select(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.SelectOrdinal); - map.Add(@"SelectMany(IQueryable`1, Expression`1>>)->IQueryable`1", SequenceMethod.SelectMany); - map.Add(@"SelectMany(IQueryable`1, Expression`1>>)->IQueryable`1", SequenceMethod.SelectManyOrdinal); - map.Add(@"SelectMany(IQueryable`1, Expression`1>>, Expression`1>)->IQueryable`1", SequenceMethod.SelectManyOrdinalResultSelector); - map.Add(@"SelectMany(IQueryable`1, Expression`1>>, Expression`1>)->IQueryable`1", SequenceMethod.SelectManyResultSelector); - map.Add(@"Join(IQueryable`1, IEnumerable`1, Expression`1>, Expression`1>, Expression`1>)->IQueryable`1", SequenceMethod.Join); - map.Add(@"Join(IQueryable`1, IEnumerable`1, Expression`1>, Expression`1>, Expression`1>, IEqualityComparer`1)->IQueryable`1", SequenceMethod.JoinComparer); - map.Add(@"GroupJoin(IQueryable`1, IEnumerable`1, Expression`1>, Expression`1>, Expression`1, T3>>)->IQueryable`1", SequenceMethod.GroupJoin); - map.Add(@"GroupJoin(IQueryable`1, IEnumerable`1, Expression`1>, Expression`1>, Expression`1, T3>>, IEqualityComparer`1)->IQueryable`1", SequenceMethod.GroupJoinComparer); - map.Add(@"OrderBy(IQueryable`1, Expression`1>)->IOrderedQueryable`1", SequenceMethod.OrderBy); - map.Add(@"OrderBy(IQueryable`1, Expression`1>, IComparer`1)->IOrderedQueryable`1", SequenceMethod.OrderByComparer); - map.Add(@"OrderByDescending(IQueryable`1, Expression`1>)->IOrderedQueryable`1", SequenceMethod.OrderByDescending); - map.Add(@"OrderByDescending(IQueryable`1, Expression`1>, IComparer`1)->IOrderedQueryable`1", SequenceMethod.OrderByDescendingComparer); - map.Add(@"ThenBy(IOrderedQueryable`1, Expression`1>)->IOrderedQueryable`1", SequenceMethod.ThenBy); - map.Add(@"ThenBy(IOrderedQueryable`1, Expression`1>, IComparer`1)->IOrderedQueryable`1", SequenceMethod.ThenByComparer); - map.Add(@"ThenByDescending(IOrderedQueryable`1, Expression`1>)->IOrderedQueryable`1", SequenceMethod.ThenByDescending); - map.Add(@"ThenByDescending(IOrderedQueryable`1, Expression`1>, IComparer`1)->IOrderedQueryable`1", SequenceMethod.ThenByDescendingComparer); - map.Add(@"Take(IQueryable`1, Int32)->IQueryable`1", SequenceMethod.Take); - map.Add(@"TakeWhile(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.TakeWhile); - map.Add(@"TakeWhile(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.TakeWhileOrdinal); - map.Add(@"Skip(IQueryable`1, Int32)->IQueryable`1", SequenceMethod.Skip); - map.Add(@"SkipWhile(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.SkipWhile); - map.Add(@"SkipWhile(IQueryable`1, Expression`1>)->IQueryable`1", SequenceMethod.SkipWhileOrdinal); - map.Add(@"GroupBy(IQueryable`1, Expression`1>)->IQueryable`1>", SequenceMethod.GroupBy); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1>)->IQueryable`1>", SequenceMethod.GroupByElementSelector); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, IEqualityComparer`1)->IQueryable`1>", SequenceMethod.GroupByComparer); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1>, IEqualityComparer`1)->IQueryable`1>", SequenceMethod.GroupByElementSelectorComparer); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1>, Expression`1, T3>>)->IQueryable`1", SequenceMethod.GroupByElementSelectorResultSelector); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1, T2>>)->IQueryable`1", SequenceMethod.GroupByResultSelector); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1, T2>>, IEqualityComparer`1)->IQueryable`1", SequenceMethod.GroupByResultSelectorComparer); - map.Add(@"GroupBy(IQueryable`1, Expression`1>, Expression`1>, Expression`1, T3>>, IEqualityComparer`1)->IQueryable`1", SequenceMethod.GroupByElementSelectorResultSelectorComparer); - map.Add(@"Distinct(IQueryable`1)->IQueryable`1", SequenceMethod.Distinct); - map.Add(@"Distinct(IQueryable`1, IEqualityComparer`1)->IQueryable`1", SequenceMethod.DistinctComparer); - map.Add(@"Concat(IQueryable`1, IEnumerable`1)->IQueryable`1", SequenceMethod.Concat); - map.Add(@"Union(IQueryable`1, IEnumerable`1)->IQueryable`1", SequenceMethod.Union); - map.Add(@"Union(IQueryable`1, IEnumerable`1, IEqualityComparer`1)->IQueryable`1", SequenceMethod.UnionComparer); - map.Add(@"Intersect(IQueryable`1, IEnumerable`1)->IQueryable`1", SequenceMethod.Intersect); - map.Add(@"Intersect(IQueryable`1, IEnumerable`1, IEqualityComparer`1)->IQueryable`1", SequenceMethod.IntersectComparer); - map.Add(@"Except(IQueryable`1, IEnumerable`1)->IQueryable`1", SequenceMethod.Except); - map.Add(@"Except(IQueryable`1, IEnumerable`1, IEqualityComparer`1)->IQueryable`1", SequenceMethod.ExceptComparer); - map.Add(@"First(IQueryable`1)->T0", SequenceMethod.First); - map.Add(@"First(IQueryable`1, Expression`1>)->T0", SequenceMethod.FirstPredicate); - map.Add(@"FirstOrDefault(IQueryable`1)->T0", SequenceMethod.FirstOrDefault); - map.Add(@"FirstOrDefault(IQueryable`1, Expression`1>)->T0", SequenceMethod.FirstOrDefaultPredicate); - map.Add(@"Last(IQueryable`1)->T0", SequenceMethod.Last); - map.Add(@"Last(IQueryable`1, Expression`1>)->T0", SequenceMethod.LastPredicate); - map.Add(@"LastOrDefault(IQueryable`1)->T0", SequenceMethod.LastOrDefault); - map.Add(@"LastOrDefault(IQueryable`1, Expression`1>)->T0", SequenceMethod.LastOrDefaultPredicate); - map.Add(@"Single(IQueryable`1)->T0", SequenceMethod.Single); - map.Add(@"Single(IQueryable`1, Expression`1>)->T0", SequenceMethod.SinglePredicate); - map.Add(@"SingleOrDefault(IQueryable`1)->T0", SequenceMethod.SingleOrDefault); - map.Add(@"SingleOrDefault(IQueryable`1, Expression`1>)->T0", SequenceMethod.SingleOrDefaultPredicate); - map.Add(@"ElementAt(IQueryable`1, Int32)->T0", SequenceMethod.ElementAt); - map.Add(@"ElementAtOrDefault(IQueryable`1, Int32)->T0", SequenceMethod.ElementAtOrDefault); - map.Add(@"DefaultIfEmpty(IQueryable`1)->IQueryable`1", SequenceMethod.DefaultIfEmpty); - map.Add(@"DefaultIfEmpty(IQueryable`1, T0)->IQueryable`1", SequenceMethod.DefaultIfEmptyValue); - map.Add(@"Contains(IQueryable`1, T0)->Boolean", SequenceMethod.Contains); - map.Add(@"Contains(IQueryable`1, T0, IEqualityComparer`1)->Boolean", SequenceMethod.ContainsComparer); - map.Add(@"Reverse(IQueryable`1)->IQueryable`1", SequenceMethod.Reverse); - map.Add(@"SequenceEqual(IQueryable`1, IEnumerable`1)->Boolean", SequenceMethod.SequenceEqual); - map.Add(@"SequenceEqual(IQueryable`1, IEnumerable`1, IEqualityComparer`1)->Boolean", SequenceMethod.SequenceEqualComparer); - map.Add(@"Any(IQueryable`1)->Boolean", SequenceMethod.Any); - map.Add(@"Any(IQueryable`1, Expression`1>)->Boolean", SequenceMethod.AnyPredicate); - map.Add(@"All(IQueryable`1, Expression`1>)->Boolean", SequenceMethod.All); - map.Add(@"Count(IQueryable`1)->Int32", SequenceMethod.Count); - map.Add(@"Count(IQueryable`1, Expression`1>)->Int32", SequenceMethod.CountPredicate); - map.Add(@"LongCount(IQueryable`1)->Int64", SequenceMethod.LongCount); - map.Add(@"LongCount(IQueryable`1, Expression`1>)->Int64", SequenceMethod.LongCountPredicate); - map.Add(@"Min(IQueryable`1)->T0", SequenceMethod.Min); - map.Add(@"Min(IQueryable`1, Expression`1>)->T1", SequenceMethod.MinSelector); - map.Add(@"Max(IQueryable`1)->T0", SequenceMethod.Max); - map.Add(@"Max(IQueryable`1, Expression`1>)->T1", SequenceMethod.MaxSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>)->Int32", SequenceMethod.SumIntSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.SumNullableIntSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>)->Int64", SequenceMethod.SumLongSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.SumNullableLongSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>)->Single", SequenceMethod.SumSingleSelector); - map.Add(@"Sum(IQueryable`1, Expression`1>>)->Nullable`1", SequenceMethod.SumNullableSingleSelector); - map.Add(@"AsQueryable(IEnumerable)->IQueryable", SequenceMethod.AsQueryable); - map.Add(@"Sum(IQueryable`1)->Int32", SequenceMethod.SumInt); - map.Add(@"Sum(IQueryable`1>)->Nullable`1", SequenceMethod.SumNullableInt); - map.Add(@"Sum(IQueryable`1)->Int64", SequenceMethod.SumLong); - map.Add(@"Sum(IQueryable`1>)->Nullable`1", SequenceMethod.SumNullableLong); - map.Add(@"Sum(IQueryable`1)->Single", SequenceMethod.SumSingle); - map.Add(@"Sum(IQueryable`1>)->Nullable`1", SequenceMethod.SumNullableSingle); - map.Add(@"Sum(IQueryable`1)->Double", SequenceMethod.SumDouble); - map.Add(@"Sum(IQueryable`1>)->Nullable`1", SequenceMethod.SumNullableDouble); - map.Add(@"Sum(IQueryable`1)->Decimal", SequenceMethod.SumDecimal); - map.Add(@"Sum(IQueryable`1>)->Nullable`1", SequenceMethod.SumNullableDecimal); - map.Add(@"Average(IQueryable`1)->Double", SequenceMethod.AverageInt); - map.Add(@"Average(IQueryable`1>)->Nullable`1", SequenceMethod.AverageNullableInt); - map.Add(@"Average(IQueryable`1)->Double", SequenceMethod.AverageLong); - map.Add(@"Average(IQueryable`1>)->Nullable`1", SequenceMethod.AverageNullableLong); - map.Add(@"Average(IQueryable`1)->Single", SequenceMethod.AverageSingle); - map.Add(@"Average(IQueryable`1>)->Nullable`1", SequenceMethod.AverageNullableSingle); - map.Add(@"Average(IQueryable`1)->Double", SequenceMethod.AverageDouble); - map.Add(@"Average(IQueryable`1>)->Nullable`1", SequenceMethod.AverageNullableDouble); - map.Add(@"Average(IQueryable`1)->Decimal", SequenceMethod.AverageDecimal); - map.Add(@"Average(IQueryable`1>)->Nullable`1", SequenceMethod.AverageNullableDecimal); - map.Add(@"First(IEnumerable`1)->T0", SequenceMethod.First); - map.Add(@"First(IEnumerable`1, Func`2)->T0", SequenceMethod.FirstPredicate); - map.Add(@"FirstOrDefault(IEnumerable`1)->T0", SequenceMethod.FirstOrDefault); - map.Add(@"FirstOrDefault(IEnumerable`1, Func`2)->T0", SequenceMethod.FirstOrDefaultPredicate); - map.Add(@"Last(IEnumerable`1)->T0", SequenceMethod.Last); - map.Add(@"Last(IEnumerable`1, Func`2)->T0", SequenceMethod.LastPredicate); - map.Add(@"LastOrDefault(IEnumerable`1)->T0", SequenceMethod.LastOrDefault); - map.Add(@"LastOrDefault(IEnumerable`1, Func`2)->T0", SequenceMethod.LastOrDefaultPredicate); - map.Add(@"Single(IEnumerable`1)->T0", SequenceMethod.Single); - map.Add(@"Single(IEnumerable`1, Func`2)->T0", SequenceMethod.SinglePredicate); - map.Add(@"SingleOrDefault(IEnumerable`1)->T0", SequenceMethod.SingleOrDefault); - map.Add(@"SingleOrDefault(IEnumerable`1, Func`2)->T0", SequenceMethod.SingleOrDefaultPredicate); - map.Add(@"ElementAt(IEnumerable`1, Int32)->T0", SequenceMethod.ElementAt); - map.Add(@"ElementAtOrDefault(IEnumerable`1, Int32)->T0", SequenceMethod.ElementAtOrDefault); - map.Add(@"Repeat(T0, Int32)->IEnumerable`1", SequenceMethod.NotSupported); - map.Add(@"Empty()->IEnumerable`1", SequenceMethod.Empty); - map.Add(@"Any(IEnumerable`1)->Boolean", SequenceMethod.Any); - map.Add(@"Any(IEnumerable`1, Func`2)->Boolean", SequenceMethod.AnyPredicate); - map.Add(@"All(IEnumerable`1, Func`2)->Boolean", SequenceMethod.All); - map.Add(@"Count(IEnumerable`1)->Int32", SequenceMethod.Count); - map.Add(@"Count(IEnumerable`1, Func`2)->Int32", SequenceMethod.CountPredicate); - map.Add(@"LongCount(IEnumerable`1)->Int64", SequenceMethod.LongCount); - map.Add(@"LongCount(IEnumerable`1, Func`2)->Int64", SequenceMethod.LongCountPredicate); - map.Add(@"Contains(IEnumerable`1, T0)->Boolean", SequenceMethod.Contains); - map.Add(@"Contains(IEnumerable`1, T0, IEqualityComparer`1)->Boolean", SequenceMethod.ContainsComparer); - map.Add(@"Aggregate(IEnumerable`1, Func`3)->T0", SequenceMethod.Aggregate); - map.Add(@"Aggregate(IEnumerable`1, T1, Func`3)->T1", SequenceMethod.AggregateSeed); - map.Add(@"Aggregate(IEnumerable`1, T1, Func`3, Func`2)->T2", SequenceMethod.AggregateSeedSelector); - map.Add(@"Sum(IEnumerable`1, Func`2)->Int32", SequenceMethod.SumIntSelector); - map.Add(@"Sum(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.SumNullableIntSelector); - map.Add(@"Sum(IEnumerable`1, Func`2)->Int64", SequenceMethod.SumLongSelector); - map.Add(@"Sum(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.SumNullableLongSelector); - map.Add(@"Sum(IEnumerable`1, Func`2)->Single", SequenceMethod.SumSingleSelector); - map.Add(@"Sum(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.SumNullableSingleSelector); - map.Add(@"Sum(IEnumerable`1, Func`2)->Double", SequenceMethod.SumDoubleSelector); - map.Add(@"Sum(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.SumNullableDoubleSelector); - map.Add(@"Sum(IEnumerable`1, Func`2)->Decimal", SequenceMethod.SumDecimalSelector); - map.Add(@"Sum(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.SumNullableDecimalSelector); - map.Add(@"Min(IEnumerable`1)->T0", SequenceMethod.Min); - map.Add(@"Min(IEnumerable`1, Func`2)->Int32", SequenceMethod.MinIntSelector); - map.Add(@"Min(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MinNullableIntSelector); - map.Add(@"Min(IEnumerable`1, Func`2)->Int64", SequenceMethod.MinLongSelector); - map.Add(@"Min(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MinNullableLongSelector); - map.Add(@"Min(IEnumerable`1, Func`2)->Single", SequenceMethod.MinSingleSelector); - map.Add(@"Min(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MinNullableSingleSelector); - map.Add(@"Min(IEnumerable`1, Func`2)->Double", SequenceMethod.MinDoubleSelector); - map.Add(@"Min(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MinNullableDoubleSelector); - map.Add(@"Min(IEnumerable`1, Func`2)->Decimal", SequenceMethod.MinDecimalSelector); - map.Add(@"Min(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MinNullableDecimalSelector); - map.Add(@"Min(IEnumerable`1, Func`2)->T1", SequenceMethod.MinSelector); - map.Add(@"Max(IEnumerable`1)->T0", SequenceMethod.Max); - map.Add(@"Max(IEnumerable`1, Func`2)->Int32", SequenceMethod.MaxIntSelector); - map.Add(@"Max(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MaxNullableIntSelector); - map.Add(@"Max(IEnumerable`1, Func`2)->Int64", SequenceMethod.MaxLongSelector); - map.Add(@"Max(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MaxNullableLongSelector); - map.Add(@"Max(IEnumerable`1, Func`2)->Single", SequenceMethod.MaxSingleSelector); - map.Add(@"Max(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MaxNullableSingleSelector); - map.Add(@"Max(IEnumerable`1, Func`2)->Double", SequenceMethod.MaxDoubleSelector); - map.Add(@"Max(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MaxNullableDoubleSelector); - map.Add(@"Max(IEnumerable`1, Func`2)->Decimal", SequenceMethod.MaxDecimalSelector); - map.Add(@"Max(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.MaxNullableDecimalSelector); - map.Add(@"Max(IEnumerable`1, Func`2)->T1", SequenceMethod.MaxSelector); - map.Add(@"Average(IEnumerable`1, Func`2)->Double", SequenceMethod.AverageIntSelector); - map.Add(@"Average(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.AverageNullableIntSelector); - map.Add(@"Average(IEnumerable`1, Func`2)->Double", SequenceMethod.AverageLongSelector); - map.Add(@"Average(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.AverageNullableLongSelector); - map.Add(@"Average(IEnumerable`1, Func`2)->Single", SequenceMethod.AverageSingleSelector); - map.Add(@"Average(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.AverageNullableSingleSelector); - map.Add(@"Average(IEnumerable`1, Func`2)->Double", SequenceMethod.AverageDoubleSelector); - map.Add(@"Average(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.AverageNullableDoubleSelector); - map.Add(@"Average(IEnumerable`1, Func`2)->Decimal", SequenceMethod.AverageDecimalSelector); - map.Add(@"Average(IEnumerable`1, Func`2>)->Nullable`1", SequenceMethod.AverageNullableDecimalSelector); - map.Add(@"Where(IEnumerable`1, Func`2)->IEnumerable`1", SequenceMethod.Where); - map.Add(@"Where(IEnumerable`1, Func`3)->IEnumerable`1", SequenceMethod.WhereOrdinal); - map.Add(@"Select(IEnumerable`1, Func`2)->IEnumerable`1", SequenceMethod.Select); - map.Add(@"Select(IEnumerable`1, Func`3)->IEnumerable`1", SequenceMethod.SelectOrdinal); - map.Add(@"SelectMany(IEnumerable`1, Func`2>)->IEnumerable`1", SequenceMethod.SelectMany); - map.Add(@"SelectMany(IEnumerable`1, Func`3>)->IEnumerable`1", SequenceMethod.SelectManyOrdinal); - map.Add(@"SelectMany(IEnumerable`1, Func`3>, Func`3)->IEnumerable`1", SequenceMethod.SelectManyOrdinalResultSelector); - map.Add(@"SelectMany(IEnumerable`1, Func`2>, Func`3)->IEnumerable`1", SequenceMethod.SelectManyResultSelector); - map.Add(@"Take(IEnumerable`1, Int32)->IEnumerable`1", SequenceMethod.Take); - map.Add(@"TakeWhile(IEnumerable`1, Func`2)->IEnumerable`1", SequenceMethod.TakeWhile); - map.Add(@"TakeWhile(IEnumerable`1, Func`3)->IEnumerable`1", SequenceMethod.TakeWhileOrdinal); - map.Add(@"Skip(IEnumerable`1, Int32)->IEnumerable`1", SequenceMethod.Skip); - map.Add(@"SkipWhile(IEnumerable`1, Func`2)->IEnumerable`1", SequenceMethod.SkipWhile); - map.Add(@"SkipWhile(IEnumerable`1, Func`3)->IEnumerable`1", SequenceMethod.SkipWhileOrdinal); - map.Add(@"Join(IEnumerable`1, IEnumerable`1, Func`2, Func`2, Func`3)->IEnumerable`1", SequenceMethod.Join); - map.Add(@"Join(IEnumerable`1, IEnumerable`1, Func`2, Func`2, Func`3, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.JoinComparer); - map.Add(@"GroupJoin(IEnumerable`1, IEnumerable`1, Func`2, Func`2, Func`3, T3>)->IEnumerable`1", SequenceMethod.GroupJoin); - map.Add(@"GroupJoin(IEnumerable`1, IEnumerable`1, Func`2, Func`2, Func`3, T3>, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.GroupJoinComparer); - map.Add(@"OrderBy(IEnumerable`1, Func`2)->IOrderedEnumerable`1", SequenceMethod.OrderBy); - map.Add(@"OrderBy(IEnumerable`1, Func`2, IComparer`1)->IOrderedEnumerable`1", SequenceMethod.OrderByComparer); - map.Add(@"OrderByDescending(IEnumerable`1, Func`2)->IOrderedEnumerable`1", SequenceMethod.OrderByDescending); - map.Add(@"OrderByDescending(IEnumerable`1, Func`2, IComparer`1)->IOrderedEnumerable`1", SequenceMethod.OrderByDescendingComparer); - map.Add(@"ThenBy(IOrderedEnumerable`1, Func`2)->IOrderedEnumerable`1", SequenceMethod.ThenBy); - map.Add(@"ThenBy(IOrderedEnumerable`1, Func`2, IComparer`1)->IOrderedEnumerable`1", SequenceMethod.ThenByComparer); - map.Add(@"ThenByDescending(IOrderedEnumerable`1, Func`2)->IOrderedEnumerable`1", SequenceMethod.ThenByDescending); - map.Add(@"ThenByDescending(IOrderedEnumerable`1, Func`2, IComparer`1)->IOrderedEnumerable`1", SequenceMethod.ThenByDescendingComparer); - map.Add(@"GroupBy(IEnumerable`1, Func`2)->IEnumerable`1>", SequenceMethod.GroupBy); - map.Add(@"GroupBy(IEnumerable`1, Func`2, IEqualityComparer`1)->IEnumerable`1>", SequenceMethod.GroupByComparer); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`2)->IEnumerable`1>", SequenceMethod.GroupByElementSelector); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`2, IEqualityComparer`1)->IEnumerable`1>", SequenceMethod.GroupByElementSelectorComparer); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`3, T2>)->IEnumerable`1", SequenceMethod.GroupByResultSelector); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`2, Func`3, T3>)->IEnumerable`1", SequenceMethod.GroupByElementSelectorResultSelector); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`3, T2>, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.GroupByResultSelectorComparer); - map.Add(@"GroupBy(IEnumerable`1, Func`2, Func`2, Func`3, T3>, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.GroupByElementSelectorResultSelectorComparer); - map.Add(@"Concat(IEnumerable`1, IEnumerable`1)->IEnumerable`1", SequenceMethod.Concat); - map.Add(@"Distinct(IEnumerable`1)->IEnumerable`1", SequenceMethod.Distinct); - map.Add(@"Distinct(IEnumerable`1, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.DistinctComparer); - map.Add(@"Union(IEnumerable`1, IEnumerable`1)->IEnumerable`1", SequenceMethod.Union); - map.Add(@"Union(IEnumerable`1, IEnumerable`1, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.UnionComparer); - map.Add(@"Intersect(IEnumerable`1, IEnumerable`1)->IEnumerable`1", SequenceMethod.Intersect); - map.Add(@"Intersect(IEnumerable`1, IEnumerable`1, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.IntersectComparer); - map.Add(@"Except(IEnumerable`1, IEnumerable`1)->IEnumerable`1", SequenceMethod.Except); - map.Add(@"Except(IEnumerable`1, IEnumerable`1, IEqualityComparer`1)->IEnumerable`1", SequenceMethod.ExceptComparer); - map.Add(@"Reverse(IEnumerable`1)->IEnumerable`1", SequenceMethod.Reverse); - map.Add(@"SequenceEqual(IEnumerable`1, IEnumerable`1)->Boolean", SequenceMethod.SequenceEqual); - map.Add(@"SequenceEqual(IEnumerable`1, IEnumerable`1, IEqualityComparer`1)->Boolean", SequenceMethod.SequenceEqualComparer); - map.Add(@"AsEnumerable(IEnumerable`1)->IEnumerable`1", SequenceMethod.AsEnumerable); - map.Add(@"ToArray(IEnumerable`1)->TSource[]", SequenceMethod.NotSupported); - map.Add(@"ToList(IEnumerable`1)->List`1", SequenceMethod.ToList); - map.Add(@"ToDictionary(IEnumerable`1, Func`2)->Dictionary`2", SequenceMethod.NotSupported); - map.Add(@"ToDictionary(IEnumerable`1, Func`2, IEqualityComparer`1)->Dictionary`2", SequenceMethod.NotSupported); - map.Add(@"ToDictionary(IEnumerable`1, Func`2, Func`2)->Dictionary`2", SequenceMethod.NotSupported); - map.Add(@"ToDictionary(IEnumerable`1, Func`2, Func`2, IEqualityComparer`1)->Dictionary`2", SequenceMethod.NotSupported); - map.Add(@"ToLookup(IEnumerable`1, Func`2)->ILookup`2", SequenceMethod.NotSupported); - map.Add(@"ToLookup(IEnumerable`1, Func`2, IEqualityComparer`1)->ILookup`2", SequenceMethod.NotSupported); - map.Add(@"ToLookup(IEnumerable`1, Func`2, Func`2)->ILookup`2", SequenceMethod.NotSupported); - map.Add(@"ToLookup(IEnumerable`1, Func`2, Func`2, IEqualityComparer`1)->ILookup`2", SequenceMethod.NotSupported); - map.Add(@"DefaultIfEmpty(IEnumerable`1)->IEnumerable`1", SequenceMethod.DefaultIfEmpty); - map.Add(@"DefaultIfEmpty(IEnumerable`1, T0)->IEnumerable`1", SequenceMethod.DefaultIfEmptyValue); - map.Add(@"OfType(IEnumerable)->IEnumerable`1", SequenceMethod.OfType); - map.Add(@"Cast(IEnumerable)->IEnumerable`1", SequenceMethod.Cast); - map.Add(@"Range(Int32, Int32)->IEnumerable`1", SequenceMethod.NotSupported); - map.Add(@"Sum(IEnumerable`1)->Int32", SequenceMethod.SumInt); - map.Add(@"Sum(IEnumerable`1>)->Nullable`1", SequenceMethod.SumNullableInt); - map.Add(@"Sum(IEnumerable`1)->Int64", SequenceMethod.SumLong); - map.Add(@"Sum(IEnumerable`1>)->Nullable`1", SequenceMethod.SumNullableLong); - map.Add(@"Sum(IEnumerable`1)->Single", SequenceMethod.SumSingle); - map.Add(@"Sum(IEnumerable`1>)->Nullable`1", SequenceMethod.SumNullableSingle); - map.Add(@"Sum(IEnumerable`1)->Double", SequenceMethod.SumDouble); - map.Add(@"Sum(IEnumerable`1>)->Nullable`1", SequenceMethod.SumNullableDouble); - map.Add(@"Sum(IEnumerable`1)->Decimal", SequenceMethod.SumDecimal); - map.Add(@"Sum(IEnumerable`1>)->Nullable`1", SequenceMethod.SumNullableDecimal); - map.Add(@"Min(IEnumerable`1)->Int32", SequenceMethod.MinInt); - map.Add(@"Min(IEnumerable`1>)->Nullable`1", SequenceMethod.MinNullableInt); - map.Add(@"Min(IEnumerable`1)->Int64", SequenceMethod.MinLong); - map.Add(@"Min(IEnumerable`1>)->Nullable`1", SequenceMethod.MinNullableLong); - map.Add(@"Min(IEnumerable`1)->Single", SequenceMethod.MinSingle); - map.Add(@"Min(IEnumerable`1>)->Nullable`1", SequenceMethod.MinNullableSingle); - map.Add(@"Min(IEnumerable`1)->Double", SequenceMethod.MinDouble); - map.Add(@"Min(IEnumerable`1>)->Nullable`1", SequenceMethod.MinNullableDouble); - map.Add(@"Min(IEnumerable`1)->Decimal", SequenceMethod.MinDecimal); - map.Add(@"Min(IEnumerable`1>)->Nullable`1", SequenceMethod.MinNullableDecimal); - map.Add(@"Max(IEnumerable`1)->Int32", SequenceMethod.MaxInt); - map.Add(@"Max(IEnumerable`1>)->Nullable`1", SequenceMethod.MaxNullableInt); - map.Add(@"Max(IEnumerable`1)->Int64", SequenceMethod.MaxLong); - map.Add(@"Max(IEnumerable`1>)->Nullable`1", SequenceMethod.MaxNullableLong); - map.Add(@"Max(IEnumerable`1)->Double", SequenceMethod.MaxDouble); - map.Add(@"Max(IEnumerable`1>)->Nullable`1", SequenceMethod.MaxNullableDouble); - map.Add(@"Max(IEnumerable`1)->Single", SequenceMethod.MaxSingle); - map.Add(@"Max(IEnumerable`1>)->Nullable`1", SequenceMethod.MaxNullableSingle); - map.Add(@"Max(IEnumerable`1)->Decimal", SequenceMethod.MaxDecimal); - map.Add(@"Max(IEnumerable`1>)->Nullable`1", SequenceMethod.MaxNullableDecimal); - map.Add(@"Average(IEnumerable`1)->Double", SequenceMethod.AverageInt); - map.Add(@"Average(IEnumerable`1>)->Nullable`1", SequenceMethod.AverageNullableInt); - map.Add(@"Average(IEnumerable`1)->Double", SequenceMethod.AverageLong); - map.Add(@"Average(IEnumerable`1>)->Nullable`1", SequenceMethod.AverageNullableLong); - map.Add(@"Average(IEnumerable`1)->Single", SequenceMethod.AverageSingle); - map.Add(@"Average(IEnumerable`1>)->Nullable`1", SequenceMethod.AverageNullableSingle); - map.Add(@"Average(IEnumerable`1)->Double", SequenceMethod.AverageDouble); - map.Add(@"Average(IEnumerable`1>)->Nullable`1", SequenceMethod.AverageNullableDouble); - map.Add(@"Average(IEnumerable`1)->Decimal", SequenceMethod.AverageDecimal); - map.Add(@"Average(IEnumerable`1>)->Nullable`1", SequenceMethod.AverageNullableDecimal); - - StaticMethodMap = new Dictionary(EqualityComparer.Default); - StaticInverseMap = new Dictionary(EqualityComparer.Default); - foreach (MethodInfo method in GetAllLinqOperators()) - { - SequenceMethod sequenceMethod; - string canonicalMethod = GetCanonicalMethodDescription(method); - if (map.TryGetValue(canonicalMethod, out sequenceMethod)) - { - StaticMethodMap.Add(method, sequenceMethod); - StaticInverseMap[sequenceMethod] = method; - } - } - - DictionaryGetItemMethodInfo = typeof(IDictionary).GetMethod("get_Item"); - TableQueryProviderReturnSingletonMethodInfo = typeof(TableQueryProvider).GetMethod("ReturnSingleton", BindingFlags.NonPublic | BindingFlags.Instance); - ProjectMethodInfo = typeof(TableQuery).GetMethods(BindingFlags.Public | BindingFlags.Static).First(m => m.Name == "Project"); - } - #endregion - - internal static bool TryIdentifySequenceMethod(MethodInfo method, out SequenceMethod sequenceMethod) - { - method = method.IsGenericMethod ? method.GetGenericMethodDefinition() : - method; - return StaticMethodMap.TryGetValue(method, out sequenceMethod); - } - - internal static bool IsSequenceMethod(MethodInfo method, SequenceMethod sequenceMethod) - { - bool result; - SequenceMethod foundSequenceMethod; - if (ReflectionUtil.TryIdentifySequenceMethod(method, out foundSequenceMethod)) - { - result = foundSequenceMethod == sequenceMethod; - } - else - { - result = false; - } - - return result; - } - -#if false - internal static bool TryIdentifySequenceMethod(Expression expression, bool unwrapLambda, out SequenceMethod sequenceMethod) - { - if (expression.NodeType == ExpressionType.Lambda && unwrapLambda) - { - expression = ((LambdaExpression)expression).Body; - } - - if (expression.NodeType == ExpressionType.Call) - { - MethodCallExpression methodCall = (MethodCallExpression)expression; - return ReflectionUtil.TryIdentifySequenceMethod(methodCall.Method, out sequenceMethod); - } - - sequenceMethod = default(SequenceMethod); - return false; - } - - internal static bool TryLookupMethod(SequenceMethod sequenceMethod, out MethodInfo method) - { - return s_inverseMap.TryGetValue(sequenceMethod, out method); - } -#endif - - internal static string GetCanonicalMethodDescription(MethodInfo method) - { - Dictionary genericArgumentOrdinals = null; - if (method.IsGenericMethodDefinition) - { - genericArgumentOrdinals = method.GetGenericArguments() - .Where(t => t.IsGenericParameter) - .Select((t, i) => new KeyValuePair(t, i)) - .ToDictionary(r => r.Key, r => r.Value); - } - - StringBuilder description = new StringBuilder(); - description.Append(method.Name).Append("("); - - bool first = true; - foreach (ParameterInfo parameter in method.GetParameters()) - { - if (first) - { - first = false; - } - else - { - description.Append(", "); - } - - AppendCanonicalTypeDescription(parameter.ParameterType, genericArgumentOrdinals, description); - } - - description.Append(")"); - - if (null != method.ReturnType) - { - description.Append("->"); - AppendCanonicalTypeDescription(method.ReturnType, genericArgumentOrdinals, description); - } - - return description.ToString(); - } - - private static void AppendCanonicalTypeDescription(Type type, Dictionary genericArgumentOrdinals, StringBuilder description) - { - int ordinal; - - if (null != genericArgumentOrdinals && genericArgumentOrdinals.TryGetValue(type, out ordinal)) - { - description.Append("T").Append(ordinal.ToString(CultureInfo.InvariantCulture)); - return; - } - - description.Append(type.Name); - - if (type.IsGenericType) - { - description.Append("<"); - bool first = true; - foreach (Type genericArgument in type.GetGenericArguments()) - { - if (first) - { - first = false; - } - else - { - description.Append(", "); - } - - AppendCanonicalTypeDescription(genericArgument, genericArgumentOrdinals, description); - } - - description.Append(">"); - } - } - - internal static IEnumerable GetAllLinqOperators() - { - return typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Concat( - typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)); - } - } - - internal enum SequenceMethod - { - Where, - WhereOrdinal, - OfType, - Cast, - Select, - SelectOrdinal, - SelectMany, - SelectManyOrdinal, - SelectManyResultSelector, - SelectManyOrdinalResultSelector, - Join, - JoinComparer, - GroupJoin, - GroupJoinComparer, - OrderBy, - OrderByComparer, - OrderByDescending, - OrderByDescendingComparer, - ThenBy, - ThenByComparer, - ThenByDescending, - ThenByDescendingComparer, - Take, - TakeWhile, - TakeWhileOrdinal, - Skip, - SkipWhile, - SkipWhileOrdinal, - GroupBy, - GroupByComparer, - GroupByElementSelector, - GroupByElementSelectorComparer, - GroupByResultSelector, - GroupByResultSelectorComparer, - GroupByElementSelectorResultSelector, - GroupByElementSelectorResultSelectorComparer, - Distinct, - DistinctComparer, - Concat, - Union, - UnionComparer, - Intersect, - IntersectComparer, - Except, - ExceptComparer, - First, - FirstPredicate, - FirstOrDefault, - FirstOrDefaultPredicate, - Last, - LastPredicate, - LastOrDefault, - LastOrDefaultPredicate, - Single, - SinglePredicate, - SingleOrDefault, - SingleOrDefaultPredicate, - ElementAt, - ElementAtOrDefault, - DefaultIfEmpty, - DefaultIfEmptyValue, - Contains, - ContainsComparer, - Reverse, - Empty, - SequenceEqual, - SequenceEqualComparer, - - Any, - AnyPredicate, - All, - - Count, - CountPredicate, - LongCount, - LongCountPredicate, - - Min, - MinSelector, - Max, - MaxSelector, - - MinInt, - MinNullableInt, - MinLong, - MinNullableLong, - MinDouble, - MinNullableDouble, - MinDecimal, - MinNullableDecimal, - MinSingle, - MinNullableSingle, - MinIntSelector, - MinNullableIntSelector, - MinLongSelector, - MinNullableLongSelector, - MinDoubleSelector, - MinNullableDoubleSelector, - MinDecimalSelector, - MinNullableDecimalSelector, - MinSingleSelector, - MinNullableSingleSelector, - - MaxInt, - MaxNullableInt, - MaxLong, - MaxNullableLong, - MaxDouble, - MaxNullableDouble, - MaxDecimal, - MaxNullableDecimal, - MaxSingle, - MaxNullableSingle, - MaxIntSelector, - MaxNullableIntSelector, - MaxLongSelector, - MaxNullableLongSelector, - MaxDoubleSelector, - MaxNullableDoubleSelector, - MaxDecimalSelector, - MaxNullableDecimalSelector, - MaxSingleSelector, - MaxNullableSingleSelector, - - SumInt, - SumNullableInt, - SumLong, - SumNullableLong, - SumDouble, - SumNullableDouble, - SumDecimal, - SumNullableDecimal, - SumSingle, - SumNullableSingle, - SumIntSelector, - SumNullableIntSelector, - SumLongSelector, - SumNullableLongSelector, - SumDoubleSelector, - SumNullableDoubleSelector, - SumDecimalSelector, - SumNullableDecimalSelector, - SumSingleSelector, - SumNullableSingleSelector, - - AverageInt, - AverageNullableInt, - AverageLong, - AverageNullableLong, - AverageDouble, - AverageNullableDouble, - AverageDecimal, - AverageNullableDecimal, - AverageSingle, - AverageNullableSingle, - AverageIntSelector, - AverageNullableIntSelector, - AverageLongSelector, - AverageNullableLongSelector, - AverageDoubleSelector, - AverageNullableDoubleSelector, - AverageDecimalSelector, - AverageNullableDecimalSelector, - AverageSingleSelector, - AverageNullableSingleSelector, - - Aggregate, - AggregateSeed, - AggregateSeedSelector, - - AsQueryable, - AsQueryableGeneric, - AsEnumerable, - - ToList, - - NotSupported, - - WithOptions, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/RequestOptionsQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/RequestOptionsQueryOptionExpression.cs deleted file mode 100644 index 375a103c3146f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/RequestOptionsQueryOptionExpression.cs +++ /dev/null @@ -1,43 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq.Expressions; - - [DebuggerDisplay("RequestOptionsQueryOptionExpression {requestOptions}")] - internal class RequestOptionsQueryOptionExpression : QueryOptionExpression - { - private ConstantExpression requestOptions; - - internal RequestOptionsQueryOptionExpression(Type type, ConstantExpression requestOptions) - : base((ExpressionType)ResourceExpressionType.RequestOptions, type) - { - this.requestOptions = requestOptions; - } - - internal ConstantExpression RequestOptions - { - get - { - return this.requestOptions; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceBinder.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceBinder.cs deleted file mode 100644 index 77664119025b8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceBinder.cs +++ /dev/null @@ -1,1501 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Diagnostics; - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - #endregion Namespaces. - - internal class ResourceBinder : DataServiceALinqExpressionVisitor - { - internal static Expression Bind(Expression e) - { - Debug.Assert(e != null, "e != null"); - - ResourceBinder rb = new ResourceBinder(); - Expression boundExpression = rb.Visit(e); - VerifyKeyPredicates(boundExpression); - VerifyNotSelectManyProjection(boundExpression); - return boundExpression; - } - - internal static bool IsMissingKeyPredicates(Expression expression) - { - ResourceExpression re = expression as ResourceExpression; - if (re != null) - { - if (IsMissingKeyPredicates(re.Source)) - { - return true; - } - - if (re.Source != null) - { - ResourceSetExpression rse = re.Source as ResourceSetExpression; - if ((rse != null) && !rse.HasKeyPredicate) - { - return true; - } - } - } - - return false; - } - - internal static void VerifyKeyPredicates(Expression e) - { - if (IsMissingKeyPredicates(e)) - { - throw new NotSupportedException(SR.ALinqCantNavigateWithoutKeyPredicate); - } - } - - internal static void VerifyNotSelectManyProjection(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - - ResourceSetExpression resourceSet = expression as ResourceSetExpression; - if (resourceSet != null) - { - ProjectionQueryOptionExpression projection = resourceSet.Projection; - if (projection != null) - { - Debug.Assert(projection.Selector != null, "projection.Selector != null -- otherwise incorrectly constructed"); - MethodCallExpression call = StripTo(projection.Selector.Body); - if (call != null && call.Method.Name == "SelectMany") - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqUnsupportedExpression, call)); - } - } - else if (resourceSet.HasTransparentScope) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqUnsupportedExpression, resourceSet)); - } - } - } - - private static Expression AnalyzePredicate(MethodCallExpression mce) - { - Debug.Assert(mce != null, "mce != null -- caller couldn't have know the expression kind otherwise"); - Debug.Assert(mce.Method.Name == "Where", "mce.Method.Name == 'Where' -- otherwise this isn't a predicate"); - - ResourceSetExpression input; - LambdaExpression le; - if (!TryGetResourceSetMethodArguments(mce, out input, out le)) - { - ValidationRules.RequireNonSingleton(mce.Arguments[0]); - return mce; - } - - List conjuncts = new List(); - AddConjuncts(le.Body, conjuncts); - - Dictionary> predicatesByTarget = new Dictionary>(ReferenceEqualityComparer.Instance); - List referencedInputs = new List(); - foreach (Expression e in conjuncts) - { - Expression reboundPredicate = InputBinder.Bind(e, input, le.Parameters[0], referencedInputs); - if (referencedInputs.Count > 1) - { - return mce; - } - - ResourceSetExpression boundTarget = referencedInputs.Count == 0 ? input : referencedInputs[0] as ResourceSetExpression; - if (boundTarget == null) - { - return mce; - } - - List targetPredicates = null; - if (!predicatesByTarget.TryGetValue(boundTarget, out targetPredicates)) - { - targetPredicates = new List(); - predicatesByTarget[boundTarget] = targetPredicates; - } - - targetPredicates.Add(reboundPredicate); - referencedInputs.Clear(); - } - - conjuncts = null; - List inputPredicates; - if (predicatesByTarget.TryGetValue(input, out inputPredicates)) - { - predicatesByTarget.Remove(input); - } - else - { - inputPredicates = null; - } - - if (inputPredicates != null) - { - if (inputPredicates.Count > 0) - { - if (input.KeyPredicate != null) - { - Expression predicateFilter = BuildKeyPredicateFilter(input.CreateReference(), input.KeyPredicate); - inputPredicates.Add(predicateFilter); - input.KeyPredicate = null; - } - - int start; - Expression newFilter; - if (input.Filter != null) - { - start = 0; - newFilter = input.Filter.Predicate; - } - else - { - start = 1; - newFilter = inputPredicates[0]; - } - - for (int idx = start; idx < inputPredicates.Count; idx++) - { - newFilter = Expression.And(newFilter, inputPredicates[idx]); - } - - AddSequenceQueryOption(input, new FilterQueryOptionExpression(mce.Method.ReturnType, newFilter)); - } - } - - return input; - } - - private static Expression BuildKeyPredicateFilter(InputReferenceExpression input, Dictionary keyValuesDictionary) - { - Debug.Assert(input != null, "input != null"); - Debug.Assert(keyValuesDictionary != null, "keyValuesDictionary != null"); - Debug.Assert(keyValuesDictionary.Count > 0, "At least one key property is required in a key predicate"); - - Expression retExpr = null; - foreach (KeyValuePair keyValue in keyValuesDictionary) - { - Expression clause = Expression.Equal(Expression.Property(input, keyValue.Key), keyValue.Value); - if (retExpr == null) - { - retExpr = clause; - } - else - { - retExpr = Expression.And(retExpr, clause); - } - } - - return retExpr; - } - - private static void AddConjuncts(Expression e, List conjuncts) - { - Debug.Assert(conjuncts != null, "conjuncts != null"); - if (PatternRules.MatchAnd(e)) - { - BinaryExpression be = (BinaryExpression)e; - AddConjuncts(be.Left, conjuncts); - AddConjuncts(be.Right, conjuncts); - } - else - { - conjuncts.Add(e); - } - } - - internal bool AnalyzeProjection(MethodCallExpression mce, SequenceMethod sequenceMethod, out Expression e) - { - Debug.Assert(mce != null, "mce != null"); - Debug.Assert( - sequenceMethod == SequenceMethod.Select || sequenceMethod == SequenceMethod.SelectManyResultSelector, - "sequenceMethod == SequenceMethod.Select(ManyResultSelector)"); - - e = mce; - - bool matchMembers = true; // TODO is this right? -> this allows us to match a single property projection i.e. ent = ent.Prop // sequenceMethod == SequenceMethod.SelectManyResultSelector; - ResourceExpression source = this.Visit(mce.Arguments[0]) as ResourceExpression; - if (source == null) - { - return false; - } - - if (sequenceMethod == SequenceMethod.SelectManyResultSelector) - { - Expression collectionSelector = mce.Arguments[1]; - if (!PatternRules.MatchParameterMemberAccess(collectionSelector)) - { - return false; - } - - Expression resultSelector = mce.Arguments[2]; - LambdaExpression resultLambda; - if (!PatternRules.MatchDoubleArgumentLambda(resultSelector, out resultLambda)) - { - return false; - } - - if (ExpressionPresenceVisitor.IsExpressionPresent(resultLambda.Parameters[0], resultLambda.Body)) - { - return false; - } - - List referencedExpressions = new List(); - LambdaExpression collectionLambda = StripTo(collectionSelector); - Expression collectorReference = InputBinder.Bind(collectionLambda.Body, source, collectionLambda.Parameters[0], referencedExpressions); - collectorReference = StripCastMethodCalls(collectorReference); - MemberExpression navigationMember; - if (!PatternRules.MatchPropertyProjectionSet(source, collectorReference, out navigationMember)) - { - return false; - } - - collectorReference = navigationMember; - - ResourceExpression resultSelectorSource = CreateResourceSetExpression(mce.Method.ReturnType, source, collectorReference, TypeSystem.GetElementType(collectorReference.Type)); - - if (!PatternRules.MatchMemberInitExpressionWithDefaultConstructor(resultSelectorSource, resultLambda) && - !PatternRules.MatchNewExpression(resultSelectorSource, resultLambda)) - { - return false; - } - -#if ASTORIA_LIGHT - resultLambda = ExpressionHelpers.CreateLambda(resultLambda.Body, new ParameterExpression[] { resultLambda.Parameters[1] }); -#else - resultLambda = Expression.Lambda(resultLambda.Body, new ParameterExpression[] { resultLambda.Parameters[1] }); -#endif - - ResourceExpression resultWithProjection = resultSelectorSource.CreateCloneWithNewType(mce.Type); - bool isProjection; - try - { - isProjection = ProjectionAnalyzer.Analyze(resultLambda, resultWithProjection, false); - } - catch (NotSupportedException) - { - isProjection = false; - } - - if (!isProjection) - { - return false; - } - - e = resultWithProjection; - ValidationRules.RequireCanProject(resultSelectorSource); - } - else - { - LambdaExpression lambda; - if (!PatternRules.MatchSingleArgumentLambda(mce.Arguments[1], out lambda)) - { - return false; - } - - lambda = ProjectionRewriter.TryToRewrite(lambda, source.ResourceType); - - ResourceExpression re = source.CreateCloneWithNewType(mce.Type); - - if (!ProjectionAnalyzer.Analyze(lambda, re, matchMembers)) - { - return false; - } - - ValidationRules.RequireCanProject(source); - e = re; - } - - return true; - } - - internal static Expression AnalyzeNavigation(MethodCallExpression mce) - { - Debug.Assert(mce != null, "mce != null"); - Expression input = mce.Arguments[0]; - LambdaExpression le; - ResourceExpression navSource; - Expression boundProjection; - MemberExpression navigationMember; - - if (!PatternRules.MatchSingleArgumentLambda(mce.Arguments[1], out le)) - { - return mce; - } - else if (PatternRules.MatchIdentitySelector(le)) - { - return input; - } - else if (PatternRules.MatchTransparentIdentitySelector(input, le)) - { - return RemoveTransparentScope(mce.Method.ReturnType, (ResourceSetExpression)input); - } - else if (IsValidNavigationSource(input, out navSource) && - TryBindToInput(navSource, le, out boundProjection) && - PatternRules.MatchPropertyProjectionSingleton(navSource, boundProjection, out navigationMember)) - { - boundProjection = navigationMember; - return CreateNavigationPropertySingletonExpression(mce.Method.ReturnType, navSource, boundProjection); - } - - return mce; - } - - private static bool IsValidNavigationSource(Expression input, out ResourceExpression sourceExpression) - { - ValidationRules.RequireCanNavigate(input); - sourceExpression = input as ResourceExpression; - return sourceExpression != null; - } - -#if !ASTORIA_LIGHT - - private static Expression LimitCardinality(MethodCallExpression mce, int maxCardinality) - { - Debug.Assert(mce != null, "mce != null"); - Debug.Assert(maxCardinality > 0, "Cardinality must be at least 1"); - - if (mce.Arguments.Count != 1) - { - return mce; - } - - ResourceSetExpression rse = mce.Arguments[0] as ResourceSetExpression; - if (rse != null) - { - if (!rse.HasKeyPredicate && - (ResourceExpressionType)rse.NodeType != ResourceExpressionType.ResourceNavigationProperty) - { - if (rse.Take == null || (int)rse.Take.TakeAmount.Value > maxCardinality) - { - AddSequenceQueryOption(rse, new TakeQueryOptionExpression(mce.Type, Expression.Constant(maxCardinality))); - } - } - - return mce.Arguments[0]; - } - else if (mce.Arguments[0] is NavigationPropertySingletonExpression) - { - return mce.Arguments[0]; - } - - return mce; - } - -#endif - - private static Expression AnalyzeCast(MethodCallExpression mce) - { - ResourceExpression re = mce.Arguments[0] as ResourceExpression; - if (re != null) - { - return re.CreateCloneWithNewType(mce.Method.ReturnType); - } - - return mce; - } - - private static ResourceSetExpression CreateResourceSetExpression(Type type, ResourceExpression source, Expression memberExpression, Type resourceType) - { - Debug.Assert(type != null, "type != null"); - Debug.Assert(source != null, "source != null"); - Debug.Assert(memberExpression != null, "memberExpression != null"); - Debug.Assert(resourceType != null, "resourceType != null"); - - Type elementType = TypeSystem.GetElementType(type); - Debug.Assert(elementType != null, "elementType != null -- otherwise the set isn't going to act like a collection"); - Type expressionType = typeof(IOrderedQueryable<>).MakeGenericType(elementType); - - ResourceSetExpression newResource = new ResourceSetExpression(expressionType, source, memberExpression, resourceType, source.ExpandPaths.ToList(), source.CountOption, source.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), null); - source.ExpandPaths.Clear(); - source.CountOption = CountOption.None; - source.CustomQueryOptions.Clear(); - return newResource; - } - - private static NavigationPropertySingletonExpression CreateNavigationPropertySingletonExpression(Type type, ResourceExpression source, Expression memberExpression) - { - NavigationPropertySingletonExpression newResource = new NavigationPropertySingletonExpression(type, source, memberExpression, memberExpression.Type, source.ExpandPaths.ToList(), source.CountOption, source.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), null); - source.ExpandPaths.Clear(); - source.CountOption = CountOption.None; - source.CustomQueryOptions.Clear(); - return newResource; - } - - private static ResourceSetExpression RemoveTransparentScope(Type expectedResultType, ResourceSetExpression input) - { - ResourceSetExpression newResource = new ResourceSetExpression(expectedResultType, input.Source, input.MemberExpression, input.ResourceType, input.ExpandPaths, input.CountOption, input.CustomQueryOptions, input.Projection); - - newResource.KeyPredicate = input.KeyPredicate; - foreach (QueryOptionExpression queryOption in input.SequenceQueryOptions) - { - newResource.AddSequenceQueryOption(queryOption); - } - - newResource.OverrideInputReference(input); - - return newResource; - } - - internal static Expression StripConvertToAssignable(Expression e) - { - Debug.Assert(e != null, "e != null"); - - Expression result; - UnaryExpression unary = e as UnaryExpression; - if (unary != null && PatternRules.MatchConvertToAssignable(unary)) - { - result = unary.Operand; - } - else - { - result = e; - } - - return result; - } - - internal static T StripTo(Expression expression) where T : Expression - { - Debug.Assert(expression != null, "expression != null"); - - Expression result; - do - { - result = expression; - expression = expression.NodeType == ExpressionType.Quote ? ((UnaryExpression)expression).Operand : expression; - expression = StripConvertToAssignable(expression); - } - while (result != expression); - - return result as T; - } - - internal override Expression VisitResourceSetExpression(ResourceSetExpression rse) - { - Debug.Assert(rse != null, "rse != null"); - - if ((ResourceExpressionType)rse.NodeType == ResourceExpressionType.RootResourceSet) - { - return new ResourceSetExpression(rse.Type, rse.Source, rse.MemberExpression, rse.ResourceType, null, CountOption.None, null, null); - } - - return rse; - } - - private static bool TryGetResourceSetMethodArguments(MethodCallExpression mce, out ResourceSetExpression input, out LambdaExpression lambda) - { - input = null; - lambda = null; - - input = mce.Arguments[0] as ResourceSetExpression; - if (input != null && - PatternRules.MatchSingleArgumentLambda(mce.Arguments[1], out lambda)) - { - return true; - } - - return false; - } - - private static bool TryBindToInput(ResourceExpression input, LambdaExpression le, out Expression bound) - { - List referencedInputs = new List(); - bound = InputBinder.Bind(le.Body, input, le.Parameters[0], referencedInputs); - if (referencedInputs.Count > 1 || (referencedInputs.Count == 1 && referencedInputs[0] != input)) - { - bound = null; - } - - return bound != null; - } - - /* - private static Expression AnalyzeResourceSetMethod(MethodCallExpression mce, Func sequenceMethodAnalyzer) - { - ResourceSetExpression input; - LambdaExpression le; - if (!TryGetResourceSetMethodArguments(mce, out input, out le)) - { - return mce; - } - - Expression lambdaBody; - if (!TryBindToInput(input, le, out lambdaBody)) - { - return mce; - } - - return sequenceMethodAnalyzer(mce, input, lambdaBody); - } - */ - - private static Expression AnalyzeResourceSetConstantMethod(MethodCallExpression mce, Func constantMethodAnalyzer) - { - ResourceExpression input = (ResourceExpression)mce.Arguments[0]; - ConstantExpression constantArg = StripTo(mce.Arguments[1]); - if (null == constantArg) - { - return mce; - } - - return constantMethodAnalyzer(mce, input, constantArg); - } - - private static Expression AnalyzeCountMethod(MethodCallExpression mce) - { - ResourceExpression re = (ResourceExpression)mce.Arguments[0]; - if (re == null) - { - return mce; - } - - ValidationRules.RequireCanAddCount(re); - ValidationRules.RequireNonSingleton(re); - re.CountOption = CountOption.ValueOnly; - - return re; - } - - private static void AddSequenceQueryOption(ResourceExpression target, QueryOptionExpression qoe) - { - ValidationRules.RequireNonSingleton(target); - ResourceSetExpression rse = (ResourceSetExpression)target; - - if (qoe.NodeType == (ExpressionType)ResourceExpressionType.FilterQueryOption) - { - if (rse.Take != null) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqQueryOptionOutOfOrder, "filter", "top")); - } - else if (rse.Projection != null) - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqQueryOptionOutOfOrder, "filter", "select")); - } - } - - rse.AddSequenceQueryOption(qoe); - } - - internal override Expression VisitBinary(BinaryExpression b) - { - Expression e = base.VisitBinary(b); - if (PatternRules.MatchStringAddition(e)) - { - BinaryExpression be = StripTo(e); - MethodInfo mi = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }); - return Expression.Call(mi, new Expression[] { be.Left, be.Right }); - } - - return e; - } - - internal override Expression VisitMemberAccess(MemberExpression m) - { - Expression e = base.VisitMemberAccess(m); - MemberExpression me = StripTo(e); - PropertyInfo pi; - MethodInfo mi; - if (me != null && - PatternRules.MatchNonPrivateReadableProperty(me, out pi) && - TypeSystem.TryGetPropertyAsMethod(pi, out mi)) - { - return Expression.Call(me.Expression, mi); - } - - return e; - } - - internal override Expression VisitMethodCall(MethodCallExpression mce) - { - Expression e; - - SequenceMethod sequenceMethod; - if (ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod)) - { - if (sequenceMethod == SequenceMethod.Select || - sequenceMethod == SequenceMethod.SelectManyResultSelector) - { - if (this.AnalyzeProjection(mce, sequenceMethod, out e)) - { - return e; - } - } - } - - e = base.VisitMethodCall(mce); - mce = e as MethodCallExpression; - - if (mce != null) - { - if (ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod)) - { - switch (sequenceMethod) - { - case SequenceMethod.Where: - return AnalyzePredicate(mce); - case SequenceMethod.Select: - return AnalyzeNavigation(mce); - case SequenceMethod.Take: - return AnalyzeResourceSetConstantMethod(mce, (callExp, resource, takeCount) => { AddSequenceQueryOption(resource, new TakeQueryOptionExpression(callExp.Type, takeCount)); return resource; }); -#if !ASTORIA_LIGHT - case SequenceMethod.First: - case SequenceMethod.FirstOrDefault: - return LimitCardinality(mce, 1); - case SequenceMethod.Single: - case SequenceMethod.SingleOrDefault: - return LimitCardinality(mce, 2); -#endif - case SequenceMethod.Cast: - return AnalyzeCast(mce); - case SequenceMethod.LongCount: - case SequenceMethod.Count: - return AnalyzeCountMethod(mce); - default: - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "The method '{0}' is not supported", mce.Method.Name)); - } - } - else if (mce.Method.DeclaringType == typeof(TableQueryableExtensions)) - { - Type[] types = mce.Method.GetGenericArguments(); - Type t = types[0]; - - if (mce.Method == TableQueryableExtensions.WithOptionsMethodInfo.MakeGenericMethod(t)) - { - return AnalyzeResourceSetConstantMethod(mce, (callExp, resource, options) => { AddSequenceQueryOption(resource, new RequestOptionsQueryOptionExpression(callExp.Type, options)); return resource; }); - } - else if (mce.Method == TableQueryableExtensions.WithContextMethodInfo.MakeGenericMethod(t)) - { - return AnalyzeResourceSetConstantMethod(mce, (callExp, resource, ctx) => { AddSequenceQueryOption(resource, new OperationContextQueryOptionExpression(callExp.Type, ctx)); return resource; }); - } - else if (types.Length > 1 && mce.Method == TableQueryableExtensions.ResolveMethodInfo.MakeGenericMethod(t, types[1])) - { - return AnalyzeResourceSetConstantMethod(mce, (callExp, resource, resolver) => { AddSequenceQueryOption(resource, new EntityResolverQueryOptionExpression(callExp.Type, resolver)); return resource; }); - } - else - { - throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "The method '{0}' is not supported", mce.Method.Name)); - } - } - - return mce; - } - - return e; - } - - private static Expression StripCastMethodCalls(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - - MethodCallExpression call = StripTo(expression); - while (call != null && ReflectionUtil.IsSequenceMethod(call.Method, SequenceMethod.Cast)) - { - expression = call.Arguments[0]; - call = StripTo(expression); - } - - return expression; - } - - internal static class PatternRules - { - internal static bool MatchConvertToAssignable(UnaryExpression expression) - { - Debug.Assert(expression != null, "expression != null"); - - if (expression.NodeType != ExpressionType.Convert && - expression.NodeType != ExpressionType.ConvertChecked && - expression.NodeType != ExpressionType.TypeAs) - { - return false; - } - - return expression.Type.IsAssignableFrom(expression.Operand.Type); - } - - internal static bool MatchParameterMemberAccess(Expression expression) - { - Debug.Assert(expression != null, "lambda != null"); - - LambdaExpression lambda = StripTo(expression); - if (lambda == null || lambda.Parameters.Count != 1) - { - return false; - } - - ParameterExpression parameter = lambda.Parameters[0]; - Expression body = StripCastMethodCalls(lambda.Body); - MemberExpression memberAccess = StripTo(body); - while (memberAccess != null) - { - if (memberAccess.Expression == parameter) - { - return true; - } - - memberAccess = StripTo(memberAccess.Expression); - } - - return false; - } - - internal static bool MatchPropertyAccess(Expression e, out MemberExpression member, out Expression instance, out List propertyPath) - { - instance = null; - propertyPath = null; - - MemberExpression me = StripTo(e); - member = me; - while (me != null) - { - PropertyInfo pi; - if (MatchNonPrivateReadableProperty(me, out pi)) - { - if (propertyPath == null) - { - propertyPath = new List(); - } - - propertyPath.Insert(0, pi.Name); - e = me.Expression; - me = StripTo(e); - } - else - { - me = null; - } - } - - if (propertyPath != null) - { - instance = e; - return true; - } - - return false; - } - - internal static bool MatchConstant(Expression e, out ConstantExpression constExpr) - { - constExpr = e as ConstantExpression; - return constExpr != null; - } - - internal static bool MatchAnd(Expression e) - { - BinaryExpression be = e as BinaryExpression; - return be != null && (be.NodeType == ExpressionType.And || be.NodeType == ExpressionType.AndAlso); - } - - internal static bool MatchNonPrivateReadableProperty(Expression e, out PropertyInfo propInfo) - { - MemberExpression me = e as MemberExpression; - if (me == null) - { - propInfo = null; - return false; - } - - return MatchNonPrivateReadableProperty(me, out propInfo); - } - - internal static bool MatchNonPrivateReadableProperty(MemberExpression me, out PropertyInfo propInfo) - { - Debug.Assert(me != null, "me != null"); - - propInfo = null; - - if (me.Member.MemberType == MemberTypes.Property) - { - PropertyInfo pi = (PropertyInfo)me.Member; - if (pi.CanRead && !TypeSystem.IsPrivate(pi)) - { - propInfo = pi; - return true; - } - } - - return false; - } - - /* - internal static bool MatchKeyProperty(Expression expression, out PropertyInfo property) - { - property = null; - - PropertyInfo pi; - if (!PatternRules.MatchNonPrivateReadableProperty(expression, out pi)) - { - return false; - } - - if (GetKeyProperties(pi.ReflectedType).Contains(pi, PropertyInfoEqualityComparer.Instance)) - { - property = pi; - return true; - } - - return false; - } - - internal static List GetKeyProperties(Type type) - { - Debug.Assert(type != null, "type != null"); - ClientType clientType = ClientType.Create(type, false); - var result = new List(); - - foreach (var property in clientType.Properties) - { - if (property.KeyProperty) - { - result.Add(property.DeclaringType.GetProperty(property.PropertyName)); - } - } - - return result; - } - - internal static bool MatchKeyComparison(Expression e, out PropertyInfo keyProperty, out ConstantExpression keyValue) - { - if (PatternRules.MatchBinaryEquality(e)) - { - BinaryExpression be = (BinaryExpression)e; - if ((PatternRules.MatchKeyProperty(be.Left, out keyProperty) && PatternRules.MatchConstant(be.Right, out keyValue)) || - (PatternRules.MatchKeyProperty(be.Right, out keyProperty) && PatternRules.MatchConstant(be.Left, out keyValue))) - { - return keyValue.Value != null; - } - } - - keyProperty = null; - keyValue = null; - return false; - } - */ - - internal static bool MatchReferenceEquals(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - MethodCallExpression call = expression as MethodCallExpression; - if (call == null) - { - return false; - } -#if WINDOWS_DESKTOP - return call.Method == typeof(object).GetMethod("ReferenceEquals"); -#elif WINDOWS_RT - return call.Method == typeof(object).GetRuntimeMethod("ReferenceEquals", new Type[]{}); -#endif - } - - internal static bool MatchResource(Expression expression, out ResourceExpression resource) - { - resource = expression as ResourceExpression; - return resource != null; - } - - internal static bool MatchDoubleArgumentLambda(Expression expression, out LambdaExpression lambda) - { - return MatchNaryLambda(expression, 2, out lambda); - } - - internal static bool MatchIdentitySelector(LambdaExpression lambda) - { - Debug.Assert(lambda != null, "lambda != null"); - - ParameterExpression parameter = lambda.Parameters[0]; - return parameter == StripTo(lambda.Body); - } - - internal static bool MatchSingleArgumentLambda(Expression expression, out LambdaExpression lambda) - { - return MatchNaryLambda(expression, 1, out lambda); - } - - internal static bool MatchTransparentIdentitySelector(Expression input, LambdaExpression selector) - { - if (selector.Parameters.Count != 1) - { - return false; - } - - ResourceSetExpression rse = input as ResourceSetExpression; - if (rse == null || rse.TransparentScope == null) - { - return false; - } - - Expression potentialRef = selector.Body; - ParameterExpression expectedTarget = selector.Parameters[0]; - - MemberExpression propertyMember; - Expression paramRef; - List refPath; - if (!MatchPropertyAccess(potentialRef, out propertyMember, out paramRef, out refPath)) - { - return false; - } - - Debug.Assert(refPath != null, "refPath != null -- otherwise MatchPropertyAccess should not have returned true"); - return paramRef == expectedTarget && refPath.Count == 1 && refPath[0] == rse.TransparentScope.Accessor; - } - - internal static bool MatchIdentityProjectionResultSelector(Expression e) - { - LambdaExpression le = (LambdaExpression)e; - return le.Body == le.Parameters[1]; - } - - internal static bool MatchTransparentScopeSelector(ResourceSetExpression input, LambdaExpression resultSelector, out ResourceSetExpression.TransparentAccessors transparentScope) - { - transparentScope = null; - - if (resultSelector.Body.NodeType != ExpressionType.New) - { - return false; - } - - NewExpression ne = (NewExpression)resultSelector.Body; - if (ne.Arguments.Count < 2) - { - return false; - } - - if (ne.Type.BaseType != typeof(object)) - { - return false; - } - - ParameterInfo[] constructorParams = ne.Constructor.GetParameters(); - if (ne.Members.Count != constructorParams.Length) - { - return false; - } - - ResourceSetExpression inputSourceSet = input.Source as ResourceSetExpression; - int introducedMemberIndex = -1; - ParameterExpression collectorSourceParameter = resultSelector.Parameters[0]; - ParameterExpression introducedRangeParameter = resultSelector.Parameters[1]; - MemberInfo[] memberProperties = new MemberInfo[ne.Members.Count]; - PropertyInfo[] properties = ne.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); - Dictionary sourceAccessors = new Dictionary(constructorParams.Length - 1, StringComparer.Ordinal); - for (int i = 0; i < ne.Arguments.Count; i++) - { - Expression argument = ne.Arguments[i]; - MemberInfo member = ne.Members[i]; - - if (!ExpressionIsSimpleAccess(argument, resultSelector.Parameters)) - { - return false; - } - - if (member.MemberType == MemberTypes.Method) - { - member = properties.Where(property => property.GetGetMethod() == member).FirstOrDefault(); - if (member == null) - { - return false; - } - } - - if (member.Name != constructorParams[i].Name) - { - return false; - } - - memberProperties[i] = member; - - ParameterExpression argumentAsParameter = StripTo(argument); - if (introducedRangeParameter == argumentAsParameter) - { - if (introducedMemberIndex != -1) - { - return false; - } - - introducedMemberIndex = i; - } - else if (collectorSourceParameter == argumentAsParameter) - { - sourceAccessors[member.Name] = inputSourceSet.CreateReference(); - } - else - { - List referencedInputs = new List(); - InputBinder.Bind(argument, inputSourceSet, resultSelector.Parameters[0], referencedInputs); - if (referencedInputs.Count != 1) - { - return false; - } - - sourceAccessors[member.Name] = referencedInputs[0].CreateReference(); - } - } - - if (introducedMemberIndex == -1) - { - return false; - } - - string resultAccessor = memberProperties[introducedMemberIndex].Name; - transparentScope = new ResourceSetExpression.TransparentAccessors(resultAccessor, sourceAccessors); - - return true; - } - - internal static bool MatchPropertyProjectionSet(ResourceExpression input, Expression potentialPropertyRef, out MemberExpression navigationMember) - { - return MatchNavigationPropertyProjection(input, potentialPropertyRef, true, out navigationMember); - } - - internal static bool MatchPropertyProjectionSingleton(ResourceExpression input, Expression potentialPropertyRef, out MemberExpression navigationMember) - { - return MatchNavigationPropertyProjection(input, potentialPropertyRef, false, out navigationMember); - } - - private static bool MatchNavigationPropertyProjection(ResourceExpression input, Expression potentialPropertyRef, bool requireSet, out MemberExpression navigationMember) - { - if (PatternRules.MatchNonSingletonProperty(potentialPropertyRef) == requireSet) - { - Expression foundInstance; - List propertyNames; - if (MatchPropertyAccess(potentialPropertyRef, out navigationMember, out foundInstance, out propertyNames)) - { - if (foundInstance == input.CreateReference()) - { - return true; - } - } - } - - navigationMember = null; - return false; - } - - internal static bool MatchMemberInitExpressionWithDefaultConstructor(Expression source, LambdaExpression e) - { - MemberInitExpression mie = StripTo(e.Body); - ResourceExpression resource; - return MatchResource(source, out resource) && (mie != null) && (mie.NewExpression.Arguments.Count == 0); - } - - internal static bool MatchNewExpression(Expression source, LambdaExpression e) - { - ResourceExpression resource; - return MatchResource(source, out resource) && (e.Body is NewExpression); - } - - internal static bool MatchNot(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - return expression.NodeType == ExpressionType.Not; - } - - internal static bool MatchNonSingletonProperty(Expression e) - { - return (TypeSystem.FindIEnumerable(e.Type) != null) && - e.Type != typeof(char[]) && - e.Type != typeof(byte[]); - } - - internal static MatchNullCheckResult MatchNullCheck(Expression entityInScope, ConditionalExpression conditional) - { - Debug.Assert(conditional != null, "conditional != null"); - - MatchNullCheckResult result = new MatchNullCheckResult(); - MatchEqualityCheckResult equalityCheck = MatchEquality(conditional.Test); - if (!equalityCheck.Match) - { - return result; - } - - Expression assignedCandidate; - if (equalityCheck.EqualityYieldsTrue) - { - if (!MatchNullConstant(conditional.IfTrue)) - { - return result; - } - - assignedCandidate = conditional.IfFalse; - } - else - { - if (!MatchNullConstant(conditional.IfFalse)) - { - return result; - } - - assignedCandidate = conditional.IfTrue; - } - - Expression memberCandidate; - if (MatchNullConstant(equalityCheck.TestLeft)) - { - memberCandidate = equalityCheck.TestRight; - } - else if (MatchNullConstant(equalityCheck.TestRight)) - { - memberCandidate = equalityCheck.TestLeft; - } - else - { - return result; - } - - Debug.Assert(assignedCandidate != null, "assignedCandidate != null"); - Debug.Assert(memberCandidate != null, "memberCandidate != null"); - - MemberAssignmentAnalysis assignedAnalysis = MemberAssignmentAnalysis.Analyze(entityInScope, assignedCandidate); - if (assignedAnalysis.MultiplePathsFound) - { - return result; - } - - MemberAssignmentAnalysis memberAnalysis = MemberAssignmentAnalysis.Analyze(entityInScope, memberCandidate); - if (memberAnalysis.MultiplePathsFound) - { - return result; - } - - Expression[] assignedExpressions = assignedAnalysis.GetExpressionsToTargetEntity(); - Expression[] memberExpressions = memberAnalysis.GetExpressionsToTargetEntity(); - if (memberExpressions.Length > assignedExpressions.Length) - { - return result; - } - - for (int i = 0; i < memberExpressions.Length; i++) - { - Expression assigned = assignedExpressions[i]; - Expression member = memberExpressions[i]; - if (assigned == member) - { - continue; - } - - if (assigned.NodeType != member.NodeType || assigned.NodeType != ExpressionType.MemberAccess) - { - return result; - } - - if (((MemberExpression)assigned).Member != ((MemberExpression)member).Member) - { - return result; - } - } - - result.AssignExpression = assignedCandidate; - result.Match = true; - result.TestToNullExpression = memberCandidate; - return result; - } - - internal static bool MatchNullConstant(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - ConstantExpression constant = expression as ConstantExpression; - if (constant != null && constant.Value == null) - { - return true; - } - - return false; - } - - internal static bool MatchBinaryExpression(Expression e) - { - return e is BinaryExpression; - } - - internal static bool MatchBinaryEquality(Expression e) - { - return PatternRules.MatchBinaryExpression(e) && ((BinaryExpression)e).NodeType == ExpressionType.Equal; - } - - internal static bool MatchStringAddition(Expression e) - { - if (e.NodeType == ExpressionType.Add) - { - BinaryExpression be = e as BinaryExpression; - return be != null && - be.Left.Type == typeof(string) && - be.Right.Type == typeof(string); - } - - return false; - } - - internal static MatchEqualityCheckResult MatchEquality(Expression expression) - { - Debug.Assert(expression != null, "expression != null"); - - MatchEqualityCheckResult result = new MatchEqualityCheckResult(); - result.Match = false; - result.EqualityYieldsTrue = true; - - while (true) - { - if (MatchReferenceEquals(expression)) - { - MethodCallExpression call = (MethodCallExpression)expression; - result.Match = true; - result.TestLeft = call.Arguments[0]; - result.TestRight = call.Arguments[1]; - break; - } - else if (MatchNot(expression)) - { - result.EqualityYieldsTrue = !result.EqualityYieldsTrue; - expression = ((UnaryExpression)expression).Operand; - } - else - { - BinaryExpression test = expression as BinaryExpression; - if (test == null) - { - break; - } - - if (test.NodeType == ExpressionType.NotEqual) - { - result.EqualityYieldsTrue = !result.EqualityYieldsTrue; - } - else if (test.NodeType != ExpressionType.Equal) - { - break; - } - - result.TestLeft = test.Left; - result.TestRight = test.Right; - result.Match = true; - break; - } - } - - return result; - } - - private static bool ExpressionIsSimpleAccess(Expression argument, ReadOnlyCollection expressions) - { - Debug.Assert(argument != null, "argument != null"); - Debug.Assert(expressions != null, "expressions != null"); - - Expression source = argument; - MemberExpression member; - do - { - member = source as MemberExpression; - if (member != null) - { - source = member.Expression; - } - } - while (member != null); - - ParameterExpression parameter = source as ParameterExpression; - if (parameter == null) - { - return false; - } - - return expressions.Contains(parameter); - } - - private static bool MatchNaryLambda(Expression expression, int parameterCount, out LambdaExpression lambda) - { - lambda = null; - - LambdaExpression le = StripTo(expression); - if (le != null && le.Parameters.Count == parameterCount) - { - lambda = le; - } - - return lambda != null; - } - - internal struct MatchNullCheckResult - { - internal Expression AssignExpression; - - internal bool Match; - - internal Expression TestToNullExpression; - } - - internal struct MatchEqualityCheckResult - { - internal bool EqualityYieldsTrue; - - internal bool Match; - - internal Expression TestLeft; - - internal Expression TestRight; - } - } - - private static class ValidationRules - { - internal static void RequireCanNavigate(Expression e) - { - ResourceSetExpression resourceSet = e as ResourceSetExpression; - if (resourceSet != null && resourceSet.HasSequenceQueryOptions) - { - throw new NotSupportedException(SR.ALinqQueryOptionsOnlyAllowedOnLeafNodes); - } - - ResourceExpression resource; - if (PatternRules.MatchResource(e, out resource) && resource.Projection != null) - { - throw new NotSupportedException(SR.ALinqQueryOptionsOnlyAllowedOnLeafNodes); - } - } - - internal static void RequireCanProject(Expression e) - { - ResourceExpression re = (ResourceExpression)e; - if (!PatternRules.MatchResource(e, out re)) - { - throw new NotSupportedException("Can only project the last entity type in the query being translated."); - } - - if (re.Projection != null) - { - throw new NotSupportedException("Cannot translate multiple Linq Select operations in a single 'select' query option."); - } - - if (re.ExpandPaths.Count > 0) - { - throw new NotSupportedException("Cannot create projection while there is an explicit expansion specified on the same query."); - } - } - - internal static void RequireCanAddCount(Expression e) - { - ResourceExpression re = (ResourceExpression)e; - if (!PatternRules.MatchResource(e, out re)) - { - throw new NotSupportedException("Cannot add count option to the resource set."); - } - - if (re.CountOption != CountOption.None) - { - throw new NotSupportedException("Cannot add count option to the resource set because it would conflict with existing count options."); - } - } - - internal static void RequireNonSingleton(Expression e) - { - ResourceExpression re = e as ResourceExpression; - if (re != null && re.IsSingleton) - { - throw new NotSupportedException("Cannot specify query options (orderby, where, take, skip) on single resource."); - } - } - } - - private sealed class PropertyInfoEqualityComparer : IEqualityComparer - { - private PropertyInfoEqualityComparer() - { - } - - internal static readonly PropertyInfoEqualityComparer Instance = new PropertyInfoEqualityComparer(); - - #region IEqualityComparer Members - - public bool Equals(PropertyInfo left, PropertyInfo right) - { - if (object.ReferenceEquals(left, right)) - { - return true; - } - - if (null == left || null == right) - { - return false; - } - - return object.ReferenceEquals(left.DeclaringType, right.DeclaringType) && left.Name.Equals(right.Name); - } - - public int GetHashCode(PropertyInfo obj) - { - Debug.Assert(obj != null, "obj != null"); - return (null != obj) ? obj.GetHashCode() : 0; - } - - #endregion - } - - private sealed class ExpressionPresenceVisitor : DataServiceALinqExpressionVisitor - { - #region Private fields. - - private readonly Expression target; - - private bool found; - - #endregion Private fields. - - private ExpressionPresenceVisitor(Expression target) - { - Debug.Assert(target != null, "target != null"); - this.target = target; - } - - internal static bool IsExpressionPresent(Expression target, Expression tree) - { - Debug.Assert(target != null, "target != null"); - Debug.Assert(tree != null, "tree != null"); - - ExpressionPresenceVisitor visitor = new ExpressionPresenceVisitor(target); - visitor.Visit(tree); - return visitor.found; - } - - internal override Expression Visit(Expression exp) - { - Expression result; - - if (this.found || object.ReferenceEquals(this.target, exp)) - { - this.found = true; - result = exp; - } - else - { - result = base.Visit(exp); - } - - return result; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpression.cs deleted file mode 100644 index eda2ac4e25332..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpression.cs +++ /dev/null @@ -1,109 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Linq.Expressions; - - #endregion Namespaces. - - internal enum CountOption - { - None, - - ValueOnly, - - InlineAll - } - - internal abstract class ResourceExpression : Expression - { - #region Fields. - - protected InputReferenceExpression inputRef; - - private List expandPaths; - - private CountOption countOption; - - private Dictionary customQueryOptions; - - private ProjectionQueryOptionExpression projection; - - #endregion Fields. - -#pragma warning disable 618 - internal ResourceExpression(Expression source, ExpressionType nodeType, Type type, List expandPaths, CountOption countOption, Dictionary customQueryOptions, ProjectionQueryOptionExpression projection) - : base(nodeType, type) - { - this.expandPaths = expandPaths ?? new List(); - this.countOption = countOption; - this.customQueryOptions = customQueryOptions ?? new Dictionary(ReferenceEqualityComparer.Instance); - this.projection = projection; - this.Source = source; - } -#pragma warning restore 618 - - abstract internal ResourceExpression CreateCloneWithNewType(Type type); - - abstract internal bool HasQueryOptions { get; } - - internal abstract Type ResourceType { get; } - - abstract internal bool IsSingleton { get; } - - internal virtual List ExpandPaths - { - get { return this.expandPaths; } - set { this.expandPaths = value; } - } - - internal virtual CountOption CountOption - { - get { return this.countOption; } - set { this.countOption = value; } - } - - internal virtual Dictionary CustomQueryOptions - { - get { return this.customQueryOptions; } - set { this.customQueryOptions = value; } - } - - internal ProjectionQueryOptionExpression Projection - { - get { return this.projection; } - set { this.projection = value; } - } - - internal Expression Source { get; private set; } - - internal InputReferenceExpression CreateReference() - { - if (this.inputRef == null) - { - this.inputRef = new InputReferenceExpression(this); - } - - return this.inputRef; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpressionType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpressionType.cs deleted file mode 100644 index 6bc3a818c286e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceExpressionType.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - internal enum ResourceExpressionType - { - RootResourceSet = 10000, - - ResourceNavigationProperty, - - ResourceNavigationPropertySingleton, - - TakeQueryOption, - - SkipQueryOption, - - OrderByQueryOption, - - FilterQueryOption, - - InputReference, - - ProjectionQueryOption, - - RequestOptions, - - OperationContext, - - Resolver, - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceSetExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceSetExpression.cs deleted file mode 100644 index 2d6362ac7caf6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/ResourceSetExpression.cs +++ /dev/null @@ -1,220 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - #region Namespaces. - - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - #endregion Namespaces. - - [DebuggerDisplay("ResourceSetExpression {Source}.{MemberExpression}")] - internal class ResourceSetExpression : ResourceExpression - { - #region Private fields. - - private readonly Type resourceType; - - private readonly Expression member; - - private Dictionary keyFilter; - - private List sequenceQueryOptions; - - private TransparentAccessors transparentScope; - - #endregion Private fields. - - internal ResourceSetExpression(Type type, Expression source, Expression memberExpression, Type resourceType, List expandPaths, CountOption countOption, Dictionary customQueryOptions, ProjectionQueryOptionExpression projection) - : base(source, source != null ? (ExpressionType)ResourceExpressionType.ResourceNavigationProperty : (ExpressionType)ResourceExpressionType.RootResourceSet, type, expandPaths, countOption, customQueryOptions, projection) - { - Debug.Assert(type != null, "type != null"); - Debug.Assert(memberExpression != null, "memberExpression != null"); - Debug.Assert(resourceType != null, "resourceType != null"); - Debug.Assert( - (source == null && memberExpression is ConstantExpression) || - (source != null && memberExpression is MemberExpression), - "source is null with constant entity set name, or not null with member expression"); - - this.member = memberExpression; - this.resourceType = resourceType; - this.sequenceQueryOptions = new List(); - } - - #region Internal properties. - - internal Expression MemberExpression - { - get { return this.member; } - } - - internal override Type ResourceType - { - get { return this.resourceType; } - } - - internal bool HasTransparentScope - { - get { return this.transparentScope != null; } - } - - internal TransparentAccessors TransparentScope - { - get { return this.transparentScope; } - set { this.transparentScope = value; } - } - - internal bool HasKeyPredicate - { - get { return this.keyFilter != null; } - } - - internal Dictionary KeyPredicate - { - get { return this.keyFilter; } - set { this.keyFilter = value; } - } - - internal override bool IsSingleton - { - get { return this.HasKeyPredicate; } - } - - internal override bool HasQueryOptions - { - get - { - return this.sequenceQueryOptions.Count > 0 || - this.ExpandPaths.Count > 0 || - this.CountOption == CountOption.InlineAll || - this.CustomQueryOptions.Count > 0 || - this.Projection != null; - } - } - - internal FilterQueryOptionExpression Filter - { - get - { - return this.sequenceQueryOptions.OfType().SingleOrDefault(); - } - } - - internal RequestOptionsQueryOptionExpression RequestOptions - { - get { return this.sequenceQueryOptions.OfType().SingleOrDefault(); } - } - - internal TakeQueryOptionExpression Take - { - get { return this.sequenceQueryOptions.OfType().SingleOrDefault(); } - } - - internal IEnumerable SequenceQueryOptions - { - get { return this.sequenceQueryOptions.ToList(); } - } - - internal bool HasSequenceQueryOptions - { - get { return this.sequenceQueryOptions.Count > 0; } - } - - #endregion Internal properties. - - #region Internal methods. - - internal override ResourceExpression CreateCloneWithNewType(Type type) - { - ResourceSetExpression rse = new ResourceSetExpression( - type, - this.Source, - this.MemberExpression, - TypeSystem.GetElementType(type), - this.ExpandPaths.ToList(), - this.CountOption, - this.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), - this.Projection); - rse.keyFilter = this.keyFilter; - rse.sequenceQueryOptions = this.sequenceQueryOptions; - rse.transparentScope = this.transparentScope; - return rse; - } - - internal void AddSequenceQueryOption(QueryOptionExpression qoe) - { - Debug.Assert(qoe != null, "qoe != null"); - QueryOptionExpression old = this.sequenceQueryOptions.Where(o => o.GetType() == qoe.GetType()).FirstOrDefault(); - if (old != null) - { - qoe = qoe.ComposeMultipleSpecification(old); - this.sequenceQueryOptions.Remove(old); - } - - this.sequenceQueryOptions.Add(qoe); - } - - internal void OverrideInputReference(ResourceSetExpression newInput) - { - Debug.Assert(newInput != null, "Original resource set cannot be null"); - Debug.Assert(this.inputRef == null, "OverrideInputReference cannot be called if the target has already been referenced"); - - InputReferenceExpression inputRef = newInput.inputRef; - if (inputRef != null) - { - this.inputRef = inputRef; - inputRef.OverrideTarget(this); - } - } - - #endregion Internal methods. - - [DebuggerDisplay("{ToString()}")] - internal class TransparentAccessors - { - #region Internal fields. - - internal readonly string Accessor; - - internal readonly Dictionary SourceAccessors; - - #endregion Internal fields. - - internal TransparentAccessors(string acc, Dictionary sourceAccesors) - { - Debug.Assert(!string.IsNullOrEmpty(acc), "Set accessor cannot be null or empty"); - Debug.Assert(sourceAccesors != null, "sourceAccesors != null"); - - this.Accessor = acc; - this.SourceAccessors = sourceAccesors; - } - - public override string ToString() - { - string result = "SourceAccessors=[" + string.Join(",", this.SourceAccessors.Keys.ToArray()); - result += "] ->* Accessor=" + this.Accessor; - return result; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TableQueryableExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TableQueryableExtensions.cs deleted file mode 100644 index b18ddb78d6c85..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TableQueryableExtensions.cs +++ /dev/null @@ -1,138 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - /// - /// Provides a set of extension methods for objects of type . - /// - public static class TableQueryableExtensions - { - internal static MethodInfo WithOptionsMethodInfo { get; set; } - - internal static MethodInfo WithContextMethodInfo { get; set; } - - internal static MethodInfo ResolveMethodInfo { get; set; } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Re-using method info collection improves performance.")] - static TableQueryableExtensions() - { - Type extensionType = typeof(TableQueryableExtensions); - MethodInfo[] methods = extensionType.GetMethods(BindingFlags.Public | BindingFlags.Static); - - TableQueryableExtensions.WithOptionsMethodInfo = methods.Where(m => m.Name == "WithOptions").FirstOrDefault(); - TableQueryableExtensions.WithContextMethodInfo = methods.Where(m => m.Name == "WithContext").FirstOrDefault(); - TableQueryableExtensions.ResolveMethodInfo = methods.Where(m => m.Name == "Resolve").FirstOrDefault(); - } - - /// - /// Specifies a set of on the query. - /// - /// The entity type of the query. - /// A query that implements . - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// A object with the specified request options set. - /// - public static TableQuery WithOptions(this IQueryable query, TableRequestOptions options) - { - CommonUtility.AssertNotNull("options", options); - - if (!(query is TableQuery)) - { - throw new NotSupportedException(SR.IQueryableExtensionObjectMustBeTableQuery); - } - - return (TableQuery)query.Provider.CreateQuery(Expression.Call( - null, - TableQueryableExtensions.WithOptionsMethodInfo.MakeGenericMethod(new Type[] { typeof(TElement) }), - new Expression[] { query.Expression, Expression.Constant(options, typeof(TableRequestOptions)) })); - } - - /// - /// Specifies an for the query. - /// - /// The entity type of the query. - /// A query that implements . - /// An object for tracking the current operation. - /// A object with the specified operation context. - /// - public static TableQuery WithContext(this IQueryable query, OperationContext operationContext) - { - CommonUtility.AssertNotNull("operationContext", operationContext); - - if (!(query is TableQuery)) - { - throw new NotSupportedException(SR.IQueryableExtensionObjectMustBeTableQuery); - } - - return (TableQuery)query.Provider.CreateQuery(Expression.Call( - null, - TableQueryableExtensions.WithContextMethodInfo.MakeGenericMethod(new Type[] { typeof(TElement) }), - new Expression[] { query.Expression, Expression.Constant(operationContext, typeof(OperationContext)) })); - } - - /// - /// Specifies an entity resolver for the query. - /// - /// The entity type of the query. - /// The type of the resolver. - /// A query that implements . - /// The entity resolver, of type . - /// A with the specified resolver. - /// - public static TableQuery Resolve(this IQueryable query, EntityResolver resolver) - { - CommonUtility.AssertNotNull("resolver", resolver); - - if (!(query is TableQuery)) - { - throw new NotSupportedException(SR.IQueryableExtensionObjectMustBeTableQuery); - } - - return (TableQuery)query.Provider.CreateQuery(Expression.Call( - null, - TableQueryableExtensions.ResolveMethodInfo.MakeGenericMethod(new Type[] { typeof(TElement), typeof(TResolved) }), - new Expression[] { query.Expression, Expression.Constant(resolver, typeof(EntityResolver)) })); - } - - /// - /// Specifies that a query be returned as a object. - /// - /// The entity type of the query. - /// A query that implements . - /// An object of type . - /// - public static TableQuery AsTableQuery(this IQueryable query) - { - TableQuery retQuery = query as TableQuery; - - if (retQuery == null) - { - throw new NotSupportedException(SR.IQueryableExtensionObjectMustBeTableQuery); - } - - return retQuery; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TakeQueryOptionExpression.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TakeQueryOptionExpression.cs deleted file mode 100644 index 28712f37f8afa..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TakeQueryOptionExpression.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Linq.Expressions; - - [DebuggerDisplay("TakeQueryOptionExpression {TakeAmount}")] - internal class TakeQueryOptionExpression : QueryOptionExpression - { - private ConstantExpression takeAmount; - - internal TakeQueryOptionExpression(Type type, ConstantExpression takeAmount) - : base((ExpressionType)ResourceExpressionType.TakeQueryOption, type) - { - this.takeAmount = takeAmount; - } - - internal ConstantExpression TakeAmount - { - get - { - return this.takeAmount; - } - } - - internal override QueryOptionExpression ComposeMultipleSpecification(QueryOptionExpression previous) - { - Debug.Assert(previous != null, "other != null"); - Debug.Assert(previous.GetType() == this.GetType(), "other.GetType == this.GetType() -- otherwise it's not the same specification"); - Debug.Assert(this.takeAmount != null, "this.takeAmount != null"); - Debug.Assert( - this.takeAmount.Type == typeof(int), - "this.takeAmount.Type == typeof(int) -- otherwise it wouldn't have matched the Enumerable.Take(source, int count) signature"); - int thisValue = (int)this.takeAmount.Value; - int previousValue = (int)((TakeQueryOptionExpression)previous).takeAmount.Value; - return (thisValue < previousValue) ? this : previous; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TypeSystem.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TypeSystem.cs deleted file mode 100644 index 6e50b2e173742..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/TypeSystem.cs +++ /dev/null @@ -1,275 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Reflection; - - internal static class TypeSystem - { - private static readonly Dictionary StaticExpressionMethodMap; - - private static readonly Dictionary StaticExpressionVBMethodMap; - - private static readonly Dictionary StaticPropertiesAsMethodsMap; - -#if !ASTORIA_LIGHT - private const string VisualBasicAssemblyFullName = "Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=" + "b03f5f7f11d50a3a"; // MicrosoftPublicKeyToken -#else - private const string VisualBasicAssemblyFullName = "Microsoft.VisualBasic, Version=2.0.5.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftSilverlightPublicKeyToken; -#endif - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Cleaner code")] - static TypeSystem() - { -#if !ASTORIA_LIGHT - const int ExpectedCount = 24; -#else - const int ExpectedCount = 22; -#endif -#if WINDOWS_DESKTOP - StaticExpressionMethodMap = new Dictionary(ExpectedCount, EqualityComparer.Default); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Contains", new Type[] { typeof(string) }), @"substringof"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), @"endswith"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), @"startswith"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) }), @"indexof"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Replace", new Type[] { typeof(string), typeof(string) }), @"replace"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Substring", new Type[] { typeof(int) }), @"substring"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Substring", new Type[] { typeof(int), typeof(int) }), @"substring"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("ToLower", Type.EmptyTypes), @"tolower"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("ToUpper", Type.EmptyTypes), @"toupper"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Trim", Type.EmptyTypes), @"trim"); - StaticExpressionMethodMap.Add(typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }, null), @"concat"); - StaticExpressionMethodMap.Add(typeof(string).GetProperty("Length", typeof(int)).GetGetMethod(), @"length"); - - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Day", typeof(int)).GetGetMethod(), @"day"); - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Hour", typeof(int)).GetGetMethod(), @"hour"); - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Month", typeof(int)).GetGetMethod(), @"month"); - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Minute", typeof(int)).GetGetMethod(), @"minute"); - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Second", typeof(int)).GetGetMethod(), @"second"); - StaticExpressionMethodMap.Add(typeof(DateTime).GetProperty("Year", typeof(int)).GetGetMethod(), @"year"); - - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Round", new Type[] { typeof(double) }), @"round"); - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Round", new Type[] { typeof(decimal) }), @"round"); - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Floor", new Type[] { typeof(double) }), @"floor"); -#if !ASTORIA_LIGHT - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Floor", new Type[] { typeof(decimal) }), @"floor"); -#endif - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Ceiling", new Type[] { typeof(double) }), @"ceiling"); -#if !ASTORIA_LIGHT - StaticExpressionMethodMap.Add(typeof(Math).GetMethod("Ceiling", new Type[] { typeof(decimal) }), @"ceiling"); -#endif - - Debug.Assert(StaticExpressionMethodMap.Count == ExpectedCount, "expressionMethodMap.Count == ExpectedCount"); - - StaticExpressionVBMethodMap = new Dictionary(EqualityComparer.Default); - - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Trim", @"trim"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Len", @"length"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Mid", @"substring"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.UCase", @"toupper"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.LCase", @"tolower"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Year", @"year"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Month", @"month"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Day", @"day"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Hour", @"hour"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Minute", @"minute"); - StaticExpressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Second", @"second"); -#elif WINDOWS_RT - expressionMethodMap = new Dictionary(ExpectedCount, EqualityComparer.Default); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Contains", new Type[] { typeof(string) }), @"substringof"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("EndsWith", new Type[] { typeof(string) }), @"endswith"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("StartsWith", new Type[] { typeof(string) }), @"startswith"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("IndexOf", new Type[] { typeof(string) }), @"indexof"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Replace", new Type[] { typeof(string), typeof(string) }), @"replace"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Substring", new Type[] { typeof(int) }), @"substring"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Substring", new Type[] { typeof(int), typeof(int) }), @"substring"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("ToLower", Type.EmptyTypes), @"tolower"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("ToUpper", Type.EmptyTypes), @"toupper"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Trim", Type.EmptyTypes), @"trim"); - expressionMethodMap.Add(typeof(string).GetRuntimeMethod("Concat", new Type[] { typeof(string), typeof(string) }), @"concat"); - expressionMethodMap.Add(typeof(string).GetRuntimeProperty("Length").GetMethod, @"length"); - - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Day").GetMethod, @"day"); - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Hour").GetMethod, @"hour"); - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Month").GetMethod, @"month"); - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Minute").GetMethod, @"minute"); - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Second").GetMethod, @"second"); - expressionMethodMap.Add(typeof(DateTime).GetRuntimeProperty("Year").GetMethod, @"year"); - - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Round", new Type[] { typeof(double) }), @"round"); - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Round", new Type[] { typeof(decimal) }), @"round"); - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Floor", new Type[] { typeof(double) }), @"floor"); -#if !ASTORIA_LIGHT - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Floor", new Type[] { typeof(decimal) }), @"floor"); -#endif - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Ceiling", new Type[] { typeof(double) }), @"ceiling"); -#if !ASTORIA_LIGHT - expressionMethodMap.Add(typeof(Math).GetRuntimeMethod("Ceiling", new Type[] { typeof(decimal) }), @"ceiling"); -#endif - - Debug.Assert(expressionMethodMap.Count == ExpectedCount, "expressionMethodMap.Count == ExpectedCount"); - - expressionVBMethodMap = new Dictionary(EqualityComparer.Default); - - expressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Trim", @"trim"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Len", @"length"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.Mid", @"substring"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.UCase", @"toupper"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.Strings.LCase", @"tolower"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Year", @"year"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Month", @"month"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Day", @"day"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Hour", @"hour"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Minute", @"minute"); - expressionVBMethodMap.Add("Microsoft.VisualBasic.DateAndTime.Second", @"second"); -#endif - Debug.Assert(StaticExpressionVBMethodMap.Count == 11, "expressionVBMethodMap.Count == 11"); - - StaticPropertiesAsMethodsMap = new Dictionary(EqualityComparer.Default); -#if WINDOWS_DESKTOP - StaticPropertiesAsMethodsMap.Add( - typeof(string).GetProperty("Length", typeof(int)), - typeof(string).GetProperty("Length", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Day", typeof(int)), - typeof(DateTime).GetProperty("Day", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Hour", typeof(int)), - typeof(DateTime).GetProperty("Hour", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Minute", typeof(int)), - typeof(DateTime).GetProperty("Minute", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Second", typeof(int)), - typeof(DateTime).GetProperty("Second", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Month", typeof(int)), - typeof(DateTime).GetProperty("Month", typeof(int)).GetGetMethod()); - StaticPropertiesAsMethodsMap.Add( - typeof(DateTime).GetProperty("Year", typeof(int)), - typeof(DateTime).GetProperty("Year", typeof(int)).GetGetMethod()); -#elif WINDOWS_RT - propertiesAsMethodsMap.Add( - typeof(string).GetRuntimeProperty("Length"), - typeof(string).GetRuntimeProperty("Length").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Day"), - typeof(DateTime).GetRuntimeProperty("Day").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Hour"), - typeof(DateTime).GetRuntimeProperty("Hour").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Minute"), - typeof(DateTime).GetRuntimeProperty("Minute").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Second"), - typeof(DateTime).GetRuntimeProperty("Second").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Month"), - typeof(DateTime).GetRuntimeProperty("Month").GetMethod); - propertiesAsMethodsMap.Add( - typeof(DateTime).GetRuntimeProperty("Year"), - typeof(DateTime).GetRuntimeProperty("Year").GetMethod); -#endif - - Debug.Assert(StaticPropertiesAsMethodsMap.Count == 7, "propertiesAsMethodsMap.Count == 7"); - } - - internal static bool TryGetQueryOptionMethod(MethodInfo mi, out string methodName) - { - return StaticExpressionMethodMap.TryGetValue(mi, out methodName) || - (mi.DeclaringType.Assembly.FullName == VisualBasicAssemblyFullName && - StaticExpressionVBMethodMap.TryGetValue(mi.DeclaringType.FullName + "." + mi.Name, out methodName)); - } - - internal static bool TryGetPropertyAsMethod(PropertyInfo pi, out MethodInfo mi) - { - return StaticPropertiesAsMethodsMap.TryGetValue(pi, out mi); - } - - internal static Type GetElementType(Type seqType) - { - Type ienum = FindIEnumerable(seqType); - if (ienum == null) - { - return seqType; - } - - return ienum.GetGenericArguments()[0]; - } - - internal static bool IsPrivate(PropertyInfo pi) - { - MethodInfo mi = pi.GetGetMethod() ?? pi.GetSetMethod(); - if (mi != null) - { - return mi.IsPrivate; - } - - return true; - } - - internal static Type FindIEnumerable(Type seqType) - { - if (seqType == null || seqType == typeof(string)) - { - return null; - } - - if (seqType.IsArray) - { - return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); - } - - if (seqType.IsGenericType) - { - foreach (Type arg in seqType.GetGenericArguments()) - { - Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); - if (ienum.IsAssignableFrom(seqType)) - { - return ienum; - } - } - } - - Type[] ifaces = seqType.GetInterfaces(); - if (ifaces != null && ifaces.Length > 0) - { - foreach (Type iface in ifaces) - { - Type ienum = FindIEnumerable(iface); - if (ienum != null) - { - return ienum; - } - } - } - - if (seqType.BaseType != null && seqType.BaseType != typeof(object)) - { - return FindIEnumerable(seqType.BaseType); - } - - return null; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/UriHelper.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/UriHelper.cs deleted file mode 100644 index c6d3b44fd5731..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/UriHelper.cs +++ /dev/null @@ -1,100 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - internal static class UriHelper - { - internal const char FORWARDSLASH = '/'; - - internal const char LEFTPAREN = '('; - - internal const char RIGHTPAREN = ')'; - - internal const char QUESTIONMARK = '?'; - - internal const char AMPERSAND = '&'; - - internal const char EQUALSSIGN = '='; - - internal const char DOLLARSIGN = '$'; - - internal const char SPACE = ' '; - - internal const char COMMA = ','; - - internal const char QUOTE = '\''; - - internal const char ASTERISK = '*'; - - internal const string OPTIONTOP = "top"; - - internal const string OPTIONSKIP = "skip"; - - internal const string OPTIONORDERBY = "orderby"; - - internal const string OPTIONFILTER = "filter"; - - internal const string OPTIONDESC = "desc"; - - internal const string OPTIONEXPAND = "expand"; - - internal const string OPTIONCOUNT = "inlinecount"; - - internal const string OPTIONSELECT = "select"; - - internal const string COUNTALL = "allpages"; - - internal const string COUNT = "count"; - - internal const string AND = "and"; - - internal const string OR = "or"; - - internal const string EQ = "eq"; - - internal const string NE = "ne"; - - internal const string LT = "lt"; - - internal const string LE = "le"; - - internal const string GT = "gt"; - - internal const string GE = "ge"; - - internal const string ADD = "add"; - - internal const string SUB = "sub"; - - internal const string MUL = "mul"; - - internal const string DIV = "div"; - - internal const string MOD = "mod"; - - internal const string NEGATE = "-"; - - internal const string NOT = "not"; - - internal const string NULL = "null"; - - internal const string ISOF = "isof"; - - internal const string CAST = "cast"; - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/WebConvert.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/WebConvert.cs deleted file mode 100644 index b1cee25a7902d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/WebConvert.cs +++ /dev/null @@ -1,722 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - using System; - using System.Diagnostics; - using System.Text; - using System.Xml; -#if ASTORIA_CLIENT - using System.Data.Services.Client; -#endif - - internal static class WebConvert - { - private const string HexValues = "0123456789ABCDEF"; - - private const string XmlHexEncodePrefix = "0x"; - -#if ASTORIA_SERVER - private static char[] XmlWhitespaceChars = new char[] { ' ', '\t', '\n', '\r' }; - - internal static bool IsCharHexDigit(char c) - { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); - } - -#endif - - internal static string ConvertByteArrayToKeyString(byte[] byteArray) - { - StringBuilder hexBuilder = new StringBuilder(3 + (byteArray.Length * 2)); - hexBuilder.Append(XmlConstants.XmlBinaryPrefix); - hexBuilder.Append("'"); - for (int i = 0; i < byteArray.Length; i++) - { - hexBuilder.Append(HexValues[byteArray[i] >> 4]); - hexBuilder.Append(HexValues[byteArray[i] & 0x0F]); - } - - hexBuilder.Append("'"); - return hexBuilder.ToString(); - } - -#if ASTORIA_SERVER - - internal static bool IsKeyValueQuoted(string text) - { - Debug.Assert(text != null, "text != null"); - if (text.Length < 2 || text[0] != '\'' || text[text.Length - 1] != '\'') - { - return false; - } - else - { - int startIndex = 1; - while (startIndex < text.Length - 1) - { - int match = text.IndexOf('\'', startIndex, text.Length - startIndex - 1); - if (match == -1) - { - break; - } - else if (match == text.Length - 2 || text[match + 1] != '\'') - { - return false; - } - else - { - startIndex = match + 2; - } - } - - return true; - } - } - -#endif - - internal static bool IsKeyTypeQuoted(Type type) - { - Debug.Assert(type != null, "type != null"); - return type == typeof(System.Xml.Linq.XElement) || type == typeof(string); - } - - internal static bool TryKeyPrimitiveToString(object value, out string result) - { - Debug.Assert(value != null, "value != null"); - if (value.GetType() == typeof(byte[])) - { - result = ConvertByteArrayToKeyString((byte[])value); - } - else - { - if (!TryXmlPrimitiveToString(value, out result)) - { - return false; - } - - Debug.Assert(result != null, "result != null"); - if (value.GetType() == typeof(DateTime)) - { - result = XmlConstants.LiteralPrefixDateTime + "'" + result + "'"; - } - else if (value.GetType() == typeof(decimal)) - { - result = result + XmlConstants.XmlDecimalLiteralSuffix; - } - else if (value.GetType() == typeof(Guid)) - { - result = XmlConstants.LiteralPrefixGuid + "'" + result + "'"; - } - else if (value.GetType() == typeof(long)) - { - result = result + XmlConstants.XmlInt64LiteralSuffix; - } - else if (value.GetType() == typeof(float)) - { - result = result + XmlConstants.XmlSingleLiteralSuffix; - } -#if ASTORIA_SERVER - else if (value.GetType() == typeof(double)) - { - double d = (double)value; - if (!Double.IsInfinity(d) && !Double.IsNaN(d)) - { - result = result + XmlConstants.XmlDoubleLiteralSuffix; - } - } -#else - else if (value.GetType() == typeof(double)) - { - result = AppendDecimalMarkerToDouble(result); - } -#endif - else if (IsKeyTypeQuoted(value.GetType())) - { - result = "'" + result.Replace("'", "''") + "'"; - } - } - - return true; - } - -#if ASTORIA_SERVER - internal static string RemoveQuotes(string text) - { - Debug.Assert(!String.IsNullOrEmpty(text), "!String.IsNullOrEmpty(text)"); - - char quote = text[0]; - Debug.Assert(quote == '\'', "quote == '\''"); - Debug.Assert(text[text.Length - 1] == '\'', "text should end with '\''."); - - string s = text.Substring(1, text.Length - 2); - int start = 0; - while (true) - { - int i = s.IndexOf(quote, start); - if (i < 0) - { - break; - } - - Debug.Assert(i + 1 < s.Length && s[i + 1] == '\'', @"Each single quote should be propertly escaped with double single quotes."); - s = s.Remove(i, 1); - start = i + 1; - } - - return s; - } - - internal static bool TryKeyStringToByteArray(string text, out byte[] targetValue) - { - Debug.Assert(text != null, "text != null"); - - if (!TryRemoveLiteralPrefix(XmlConstants.LiteralPrefixBinary, ref text) && - !TryRemoveLiteralPrefix(XmlConstants.XmlBinaryPrefix, ref text)) - { - targetValue = null; - return false; - } - - if (!TryRemoveQuotes(ref text)) - { - targetValue = null; - return false; - } - - if ((text.Length % 2) != 0) - { - targetValue = null; - return false; - } - - byte[] result = new byte[text.Length / 2]; - int resultIndex = 0; - int textIndex = 0; - while (resultIndex < result.Length) - { - char ch0 = text[textIndex]; - char ch1 = text[textIndex + 1]; - if (!IsCharHexDigit(ch0) || !IsCharHexDigit(ch1)) - { - targetValue = null; - return false; - } - - result[resultIndex] = (byte)((byte)(HexCharToNibble(ch0) << 4) + HexCharToNibble(ch1)); - textIndex += 2; - resultIndex++; - } - - targetValue = result; - return true; - } - - internal static bool TryKeyStringToDateTime(string text, out DateTime targetValue) - { - if (!TryRemoveLiteralPrefix(XmlConstants.LiteralPrefixDateTime, ref text)) - { - targetValue = default(DateTime); - return false; - } - - if (!TryRemoveQuotes(ref text)) - { - targetValue = default(DateTime); - return false; - } - - try - { - targetValue = XmlConvert.ToDateTime(text, XmlDateTimeSerializationMode.RoundtripKind); - return true; - } - catch (FormatException) - { - targetValue = default(DateTime); - return false; - } - } - - internal static bool TryKeyStringToGuid(string text, out Guid targetValue) - { - if (!TryRemoveLiteralPrefix(XmlConstants.LiteralPrefixGuid, ref text)) - { - targetValue = default(Guid); - return false; - } - - if (!TryRemoveQuotes(ref text)) - { - targetValue = default(Guid); - return false; - } - - try - { - targetValue = XmlConvert.ToGuid(text); - return true; - } - catch (FormatException) - { - targetValue = default(Guid); - return false; - } - } - - internal static bool TryKeyStringToPrimitive(string text, Type targetType, out object targetValue) - { - Debug.Assert(text != null, "text != null"); - Debug.Assert(targetType != null, "targetType != null"); - - targetType = Nullable.GetUnderlyingType(targetType) ?? targetType; - - byte[] byteArrayValue; - bool binaryResult = TryKeyStringToByteArray(text, out byteArrayValue); - if (targetType == typeof(byte[]) || targetType == typeof(System.Data.Linq.Binary)) - { - targetValue = - (byteArrayValue != null && targetType == typeof(System.Data.Linq.Binary)) ? - (object)new System.Data.Linq.Binary(byteArrayValue) : (object)byteArrayValue; - return binaryResult; - } - else if (binaryResult) - { - string keyValue = Encoding.UTF8.GetString(byteArrayValue); - return TryKeyStringToPrimitive(keyValue, targetType, out targetValue); - } - else if (targetType == typeof(Guid)) - { - Guid guidValue; - bool result = TryKeyStringToGuid(text, out guidValue); - targetValue = guidValue; - return result; - } - else if (targetType == typeof(DateTime)) - { - DateTime dateTimeValue; - bool result = TryKeyStringToDateTime(text, out dateTimeValue); - targetValue = dateTimeValue; - return result; - } - - bool quoted = WebConvert.IsKeyTypeQuoted(targetType); - if (quoted != WebConvert.IsKeyValueQuoted(text)) - { - targetValue = null; - return false; - } - - if (quoted) - { - Debug.Assert(IsKeyValueQuoted(text), "IsKeyValueQuoted(text) - otherwise caller didn't check this before"); - text = RemoveQuotes(text); - } - - try - { - if (typeof(String) == targetType) - { - targetValue = text; - } - else if (typeof(Boolean) == targetType) - { - targetValue = XmlConvert.ToBoolean(text); - } - else if (typeof(Byte) == targetType) - { - targetValue = XmlConvert.ToByte(text); - } - else if (typeof(SByte) == targetType) - { - targetValue = XmlConvert.ToSByte(text); - } - else if (typeof(Int16) == targetType) - { - targetValue = XmlConvert.ToInt16(text); - } - else if (typeof(Int32) == targetType) - { - targetValue = XmlConvert.ToInt32(text); - } - else if (typeof(Int64) == targetType) - { - if (TryRemoveLiteralSuffix(XmlConstants.XmlInt64LiteralSuffix, ref text)) - { - targetValue = XmlConvert.ToInt64(text); - } - else - { - targetValue = default(Int64); - return false; - } - } - else if (typeof(Single) == targetType) - { - if (TryRemoveLiteralSuffix(XmlConstants.XmlSingleLiteralSuffix, ref text)) - { - targetValue = XmlConvert.ToSingle(text); - } - else - { - targetValue = default(Single); - return false; - } - } - else if (typeof(Double) == targetType) - { - TryRemoveLiteralSuffix(XmlConstants.XmlDoubleLiteralSuffix, ref text); - targetValue = XmlConvert.ToDouble(text); - } - else if (typeof(Decimal) == targetType) - { - if (TryRemoveLiteralSuffix(XmlConstants.XmlDecimalLiteralSuffix, ref text)) - { - try - { - targetValue = XmlConvert.ToDecimal(text); - } - catch (FormatException) - { - decimal result; - if (Decimal.TryParse(text, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out result)) - { - targetValue = result; - } - else - { - targetValue = default(Decimal); - return false; - } - } - } - else - { - targetValue = default(Decimal); - return false; - } - } - else - { - Debug.Assert(typeof(System.Xml.Linq.XElement) == targetType, "XElement == " + targetType); - targetValue = System.Xml.Linq.XElement.Parse(text, System.Xml.Linq.LoadOptions.PreserveWhitespace); - } - - return true; - } - catch (FormatException) - { - targetValue = null; - return false; - } - } - - internal static object StringToPrimitive(string text, Type targetType) - { - Debug.Assert(text != null, "text != null"); - Debug.Assert(targetType != null, "targetType != null"); - - object targetValue = null; - targetType = Nullable.GetUnderlyingType(targetType) ?? targetType; - - if (typeof(String) == targetType) - { - targetValue = text; - } - else if (typeof(Boolean) == targetType) - { - targetValue = XmlConvert.ToBoolean(text); - } - else if (typeof(Byte) == targetType) - { - targetValue = XmlConvert.ToByte(text); - } - else if (typeof(byte[]) == targetType) - { - targetValue = Convert.FromBase64String(text); - } - else if (typeof(System.Data.Linq.Binary) == targetType) - { - targetValue = new System.Data.Linq.Binary(Convert.FromBase64String(text)); - } - else if (typeof(SByte) == targetType) - { - targetValue = XmlConvert.ToSByte(text); - } - else if (typeof(DateTime) == targetType) - { - targetValue = XmlConvert.ToDateTime(text, XmlDateTimeSerializationMode.RoundtripKind); - } - else if (typeof(Decimal) == targetType) - { - targetValue = XmlConvert.ToDecimal(text); - } - else if (typeof(Double) == targetType) - { - targetValue = XmlConvert.ToDouble(text); - } - else if (typeof(Guid) == targetType) - { - targetValue = new Guid(text); - } - else if (typeof(Int16) == targetType) - { - targetValue = XmlConvert.ToInt16(text); - } - else if (typeof(Int32) == targetType) - { - targetValue = XmlConvert.ToInt32(text); - } - else if (typeof(Int64) == targetType) - { - targetValue = XmlConvert.ToInt64(text); - } - else if (typeof(System.Xml.Linq.XElement) == targetType) - { - targetValue = System.Xml.Linq.XElement.Parse(text, System.Xml.Linq.LoadOptions.PreserveWhitespace); - } - else - { - Debug.Assert(typeof(Single) == targetType, "typeof(Single) == targetType(" + targetType + ")"); - targetValue = XmlConvert.ToSingle(text); - } - - return targetValue; - } - - internal static bool TryRemoveQuotes(ref string text) - { - if (text.Length < 2) - { - return false; - } - - char quote = text[0]; - if (quote != '\'' || text[text.Length - 1] != quote) - { - return false; - } - - string s = text.Substring(1, text.Length - 2); - int start = 0; - while (true) - { - int i = s.IndexOf(quote, start); - if (i < 0) - { - break; - } - - s = s.Remove(i, 1); - if (s.Length < i + 1 || s[i] != quote) - { - return false; - } - - start = i + 1; - } - - text = s; - return true; - } -#endif - - internal static bool TryXmlPrimitiveToString(object value, out string result) - { - Debug.Assert(value != null, "value != null"); - result = null; - - Type valueType = value.GetType(); - valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; - - if (typeof(string) == valueType) - { - result = (string)value; - } - else if (typeof(bool) == valueType) - { - result = XmlConvert.ToString((bool)value); - } - else if (typeof(byte) == valueType) - { - result = XmlConvert.ToString((byte)value); - } - else if (typeof(DateTime) == valueType) - { - result = XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.RoundtripKind); - } - else if (typeof(decimal) == valueType) - { - result = XmlConvert.ToString((decimal)value); - } - else if (typeof(double) == valueType) - { - result = XmlConvert.ToString((double)value); - } - else if (typeof(Guid) == valueType) - { - result = value.ToString(); - } - else if (typeof(short) == valueType) - { - result = XmlConvert.ToString((short)value); - } - else if (typeof(int) == valueType) - { - result = XmlConvert.ToString((int)value); - } - else if (typeof(long) == valueType) - { - result = XmlConvert.ToString((long)value); - } - else if (typeof(sbyte) == valueType) - { - result = XmlConvert.ToString((sbyte)value); - } - else if (typeof(float) == valueType) - { - result = XmlConvert.ToString((float)value); - } - else if (typeof(byte[]) == valueType) - { - byte[] byteArray = (byte[])value; - result = Convert.ToBase64String(byteArray); - } -#if ASTORIA_SERVER - else if (typeof(System.Data.Linq.Binary) == valueType) - { - return TryXmlPrimitiveToString(((System.Data.Linq.Binary)value).ToArray(), out result); - } -#else -#if !ASTORIA_LIGHT - else if (ClientConvert.IsBinaryValue(value)) - { - return ClientConvert.TryKeyBinaryToString(value, out result); - } -#endif -#endif - else if (typeof(System.Xml.Linq.XElement) == valueType) - { - result = ((System.Xml.Linq.XElement)value).ToString(System.Xml.Linq.SaveOptions.None); - } - else - { - result = null; - return false; - } - - Debug.Assert(result != null, "result != null"); - return true; - } - -#if ASTORIA_SERVER - private static byte HexCharToNibble(char c) - { - Debug.Assert(IsCharHexDigit(c)); - switch (c) - { - case '0': - return 0; - case '1': - return 1; - case '2': - return 2; - case '3': - return 3; - case '4': - return 4; - case '5': - return 5; - case '6': - return 6; - case '7': - return 7; - case '8': - return 8; - case '9': - return 9; - case 'a': - case 'A': - return 10; - case 'b': - case 'B': - return 11; - case 'c': - case 'C': - return 12; - case 'd': - case 'D': - return 13; - case 'e': - case 'E': - return 14; - case 'f': - case 'F': - return 15; - default: - throw new InvalidOperationException(); - } - } - - private static bool TryRemoveLiteralSuffix(string suffix, ref string text) - { - Debug.Assert(text != null, "text != null"); - Debug.Assert(suffix != null, "suffix != null"); - - text = text.Trim(XmlWhitespaceChars); - if (text.Length <= suffix.Length || !text.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) - { - return false; - } - else - { - text = text.Substring(0, text.Length - suffix.Length); - return true; - } - } - - private static bool TryRemoveLiteralPrefix(string prefix, ref string text) - { - Debug.Assert(prefix != null, "prefix != null"); - if (text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - text = text.Remove(0, prefix.Length); - return true; - } - else - { - return false; - } - } -#else - private static string AppendDecimalMarkerToDouble(string input) - { - foreach (char c in input) - { - if (!char.IsDigit(c)) - { - return input; - } - } - - return input + ".0"; - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/XmlConstants.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/XmlConstants.cs deleted file mode 100644 index 0aacce66f1e08..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/Queryable/XmlConstants.cs +++ /dev/null @@ -1,628 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Queryable -{ - internal static class XmlConstants - { - #region CLR / Reflection constants. - - internal const string ClrServiceInitializationMethodName = "InitializeService"; - - #endregion CLR / Reflection constants. - - #region HTTP constants. - - internal const string HttpContentID = "Content-ID"; - - internal const string HttpContentLength = "Content-Length"; - - internal const string HttpContentType = "Content-Type"; - - internal const string HttpContentDisposition = "Content-Disposition"; - - internal const string HttpDataServiceVersion = "DataServiceVersion"; - - internal const string HttpMaxDataServiceVersion = "MaxDataServiceVersion"; - - internal const string HttpCacheControlNoCache = "no-cache"; - - internal const string HttpCharsetParameter = "charset"; - - internal const string HttpMethodGet = "GET"; - - internal const string HttpMethodPost = "POST"; - - internal const string HttpMethodPut = "PUT"; - - internal const string HttpMethodDelete = "DELETE"; - - internal const string HttpMethodMerge = "MERGE"; - - internal const string HttpQueryStringExpand = "$expand"; - - internal const string HttpQueryStringFilter = "$filter"; - - internal const string HttpQueryStringOrderBy = "$orderby"; - - internal const string HttpQueryStringSkip = "$skip"; - - internal const string HttpQueryStringTop = "$top"; - - internal const string HttpQueryStringInlineCount = "$inlinecount"; - - internal const string HttpQueryStringSkipToken = "$skiptoken"; - - internal const string SkipTokenPropertyPrefix = "SkipTokenProperty"; - - internal const string HttpQueryStringValueCount = "$count"; - - internal const string HttpQueryStringSelect = "$select"; - - internal const string HttpQValueParameter = "q"; - - internal const string HttpXMethod = "X-HTTP-Method"; - - internal const string HttpRequestAccept = "Accept"; - - internal const string HttpRequestAcceptCharset = "Accept-Charset"; - - internal const string HttpRequestIfMatch = "If-Match"; - - internal const string HttpRequestIfNoneMatch = "If-None-Match"; - - internal const string HttpMultipartBoundary = "boundary"; -#if ASTORIA_CLIENT - internal const string HttpMultipartBoundaryBatch = "batch"; - - internal const string HttpMultipartBoundaryChangeSet = "changeset"; -#endif - - internal const string HttpResponseAllow = "Allow"; - - internal const string HttpResponseCacheControl = "Cache-Control"; - - internal const string HttpResponseETag = "ETag"; - - internal const string HttpResponseLocation = "Location"; - - internal const string HttpResponseStatusCode = "Status-Code"; - - internal const string HttpMultipartBoundaryBatchResponse = "batchresponse"; - - internal const string HttpMultipartBoundaryChangesetResponse = "changesetresponse"; - - internal const string HttpContentTransferEncoding = "Content-Transfer-Encoding"; - - internal const string HttpVersionInBatching = "HTTP/1.1"; - - internal const string HttpAnyETag = "*"; - - internal const string HttpWeakETagPrefix = "W/\""; - - internal const string HttpAcceptCharset = "Accept-Charset"; - - internal const string HttpCookie = "Cookie"; - - internal const string HttpSlug = "Slug"; - - #endregion HTTP constants. - - #region MIME constants. - - internal const string MimeAny = "*/*"; - - internal const string MimeApplicationAtom = "application/atom+xml"; - - internal const string MimeApplicationAtomService = "application/atomsvc+xml"; - - internal const string MimeApplicationJson = "application/json"; - - internal const string MimeApplicationOctetStream = "application/octet-stream"; - - internal const string MimeApplicationHttp = "application/http"; - - internal const string MimeApplicationType = "application"; - - internal const string MimeApplicationXml = "application/xml"; - - internal const string MimeJsonSubType = "json"; - - internal const string MimeMetadata = MimeApplicationXml; - - internal const string MimeMultiPartMixed = "multipart/mixed"; - - internal const string MimeTextPlain = "text/plain"; - - internal const string MimeTextType = "text"; - - internal const string MimeTextXml = "text/xml"; - - internal const string MimeXmlSubType = "xml"; - - internal const string BatchRequestContentTransferEncoding = "binary"; - -#if ASTORIA_CLIENT - internal const string LinkMimeTypeFeed = "application/atom+xml;type=feed"; - - internal const string LinkMimeTypeEntry = "application/atom+xml;type=entry"; - - internal const string Utf8Encoding = "UTF-8"; - - internal const string MimeTypeUtf8Encoding = ";charset=" + Utf8Encoding; -#endif - #endregion MIME constants. - - #region URI constants. - - internal const string UriHttpAbsolutePrefix = "http://host"; - - internal const string UriMetadataSegment = "$metadata"; - - internal const string UriValueSegment = "$value"; - - internal const string UriBatchSegment = "$batch"; - - internal const string UriLinkSegment = "$links"; - - internal const string UriCountSegment = "$count"; - - internal const string UriRowCountAllOption = "allpages"; - - internal const string UriRowCountOffOption = "none"; - - #endregion URI constants. - - #region WCF constants. - - internal const string WcfBinaryElementName = "Binary"; - - #endregion WCF constants. - - #region ATOM constants - internal const string AtomContentElementName = "content"; - - internal const string AtomEntryElementName = "entry"; - - internal const string AtomFeedElementName = "feed"; - -#if ASTORIA_CLIENT - internal const string AtomAuthorElementName = "author"; - - internal const string AtomContributorElementName = "contributor"; - - internal const string AtomCategoryElementName = "category"; - - internal const string AtomCategorySchemeAttributeName = "scheme"; - - internal const string AtomCategoryTermAttributeName = "term"; - - internal const string AtomIdElementName = "id"; - - internal const string AtomLinkElementName = "link"; - - internal const string AtomLinkRelationAttributeName = "rel"; - - internal const string AtomContentSrcAttributeName = "src"; - - internal const string AtomLinkNextAttributeString = "next"; - -#endif - internal const string MetadataAttributeEpmContentKind = "FC_ContentKind"; - - internal const string MetadataAttributeEpmKeepInContent = "FC_KeepInContent"; - - internal const string MetadataAttributeEpmNsPrefix = "FC_NsPrefix"; - - internal const string MetadataAttributeEpmNsUri = "FC_NsUri"; - - internal const string MetadataAttributeEpmTargetPath = "FC_TargetPath"; - - internal const string MetadataAttributeEpmSourcePath = "FC_SourcePath"; - - internal const string SyndAuthorEmail = "SyndicationAuthorEmail"; - - internal const string SyndAuthorName = "SyndicationAuthorName"; - - internal const string SyndAuthorUri = "SyndicationAuthorUri"; - - internal const string SyndPublished = "SyndicationPublished"; - - internal const string SyndRights = "SyndicationRights"; - - internal const string SyndSummary = "SyndicationSummary"; - - internal const string SyndTitle = "SyndicationTitle"; - - internal const string AtomUpdatedElementName = "updated"; - - internal const string SyndContributorEmail = "SyndicationContributorEmail"; - - internal const string SyndContributorName = "SyndicationContributorName"; - - internal const string SyndContributorUri = "SyndicationContributorUri"; - - internal const string SyndUpdated = "SyndicationUpdated"; - - internal const string SyndContentKindPlaintext = "text"; - - internal const string SyndContentKindHtml = "html"; - - internal const string SyndContentKindXHtml = "xhtml"; - - internal const string AtomHRefAttributeName = "href"; - - internal const string AtomSummaryElementName = "summary"; - - internal const string AtomNameElementName = "name"; - - internal const string AtomEmailElementName = "email"; - - internal const string AtomUriElementName = "uri"; - - internal const string AtomPublishedElementName = "published"; - - internal const string AtomRightsElementName = "rights"; - - internal const string AtomPublishingCollectionElementName = "collection"; - - internal const string AtomPublishingServiceElementName = "service"; - - internal const string AtomPublishingWorkspaceDefaultValue = "Default"; - - internal const string AtomPublishingWorkspaceElementName = "workspace"; - - internal const string AtomTitleElementName = "title"; - - internal const string AtomTypeAttributeName = "type"; - - internal const string AtomSelfRelationAttributeValue = "self"; - - internal const string AtomEditRelationAttributeValue = "edit"; - - internal const string AtomEditMediaRelationAttributeValue = "edit-media"; - - internal const string AtomNullAttributeName = "null"; - - internal const string AtomETagAttributeName = "etag"; - - internal const string AtomInlineElementName = "inline"; - - internal const string AtomPropertiesElementName = "properties"; - - internal const string RowCountElement = "count"; - - #endregion ATOM constants - - #region XML constants. - - internal const string XmlCollectionItemElementName = "element"; - - internal const string XmlErrorElementName = "error"; - - internal const string XmlErrorCodeElementName = "code"; - - internal const string XmlErrorInnerElementName = "innererror"; - - internal const string XmlErrorInternalExceptionElementName = "internalexception"; - - internal const string XmlErrorTypeElementName = "type"; - - internal const string XmlErrorStackTraceElementName = "stacktrace"; - - internal const string XmlErrorMessageElementName = "message"; - - internal const string XmlFalseLiteral = "false"; - - internal const string XmlTrueLiteral = "true"; - - internal const string XmlInfinityLiteral = "INF"; - - internal const string XmlNaNLiteral = "NaN"; - - internal const string XmlBaseAttributeName = "base"; - - internal const string XmlLangAttributeName = "lang"; - - internal const string XmlSpaceAttributeName = "space"; - - internal const string XmlSpacePreserveValue = "preserve"; - - internal const string XmlBaseAttributeNameWithPrefix = "xml:base"; - - #endregion XML constants. - - #region XML namespaces. - - internal const string EdmV1Namespace = "http://schemas.microsoft.com/ado/2006/04/edm"; - - internal const string EdmV1dot1Namespace = "http://schemas.microsoft.com/ado/2007/05/edm"; - - internal const string EdmV1dot2Namespace = "http://schemas.microsoft.com/ado/2008/01/edm"; - - internal const string EdmV2Namespace = "http://schemas.microsoft.com/ado/2008/09/edm"; - - internal const string DataWebNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices"; - - internal const string DataWebMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"; - - internal const string DataWebRelatedNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/related/"; - - internal const string DataWebSchemeNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"; - - internal const string AppNamespace = "http://www.w3.org/2007/app"; - - internal const string AtomNamespace = "http://www.w3.org/2005/Atom"; - - internal const string XmlnsNamespacePrefix = "xmlns"; - - internal const string XmlNamespacePrefix = "xml"; - - internal const string DataWebNamespacePrefix = "d"; - - internal const string DataWebMetadataNamespacePrefix = "m"; - - internal const string XmlNamespacesNamespace = "http://www.w3.org/2000/xmlns/"; - - internal const string EdmxNamespace = "http://schemas.microsoft.com/ado/2007/06/edmx"; - - internal const string EdmxNamespacePrefix = "edmx"; - - #endregion XML namespaces. - - #region CDM Schema Xml NodeNames - - #region Constant node names in the CDM schema xml - - internal const string Association = "Association"; - - internal const string AssociationSet = "AssociationSet"; - - internal const string ComplexType = "ComplexType"; - - internal const string Dependent = "Dependent"; - - internal const string EdmCollectionTypeFormat = "Collection({0})"; - - internal const string EdmEntitySetAttributeName = "EntitySet"; - - internal const string EdmFunctionImportElementName = "FunctionImport"; - - internal const string EdmModeAttributeName = "Mode"; - - internal const string EdmModeInValue = "In"; - - internal const string EdmParameterElementName = "Parameter"; - - internal const string EdmReturnTypeAttributeName = "ReturnType"; - - internal const string End = "End"; - - internal const string EntityType = "EntityType"; - - internal const string EntityContainer = "EntityContainer"; - - internal const string Key = "Key"; - - internal const string NavigationProperty = "NavigationProperty"; - - internal const string OnDelete = "OnDelete"; - - internal const string Principal = "Principal"; - - internal const string Property = "Property"; - - internal const string PropertyRef = "PropertyRef"; - - internal const string ReferentialConstraint = "ReferentialConstraint"; - - internal const string Role = "Role"; - - internal const string Schema = "Schema"; - - internal const string EdmxElement = "Edmx"; - - internal const string EdmxDataServicesElement = "DataServices"; - - internal const string EdmxVersion = "Version"; - - internal const string EdmxVersionValue = "1.0"; - - #endregion //Constant node names in the CDM schema xml - - #region const attribute names in the CDM schema XML - - internal const string Action = "Action"; - - internal const string BaseType = "BaseType"; - - internal const string EntitySet = "EntitySet"; - - internal const string FromRole = "FromRole"; - - internal const string Abstract = "Abstract"; - - internal const string Multiplicity = "Multiplicity"; - - internal const string Name = "Name"; - - internal const string Namespace = "Namespace"; - - internal const string ToRole = "ToRole"; - - internal const string Type = "Type"; - - internal const string Relationship = "Relationship"; - #endregion //const attribute names in the CDM schema XML - - #region values for multiplicity in Edm - - internal const string Many = "*"; - - internal const string One = "1"; - - internal const string ZeroOrOne = "0..1"; - #endregion - - #region Edm Facets Names and Values - - internal const string Nullable = "Nullable"; - - internal const string ConcurrencyAttribute = "ConcurrencyMode"; - - internal const string ConcurrencyFixedValue = "Fixed"; - - #endregion - - #endregion - - #region DataWeb Elements and Attributes. - - internal const string DataWebMimeTypeAttributeName = "MimeType"; - - internal const string DataWebOpenTypeAttributeName = "OpenType"; - - internal const string DataWebAccessHasStreamAttribute = "HasStream"; - - internal const string DataWebAccessDefaultStreamPropertyValue = "true"; - - internal const string IsDefaultEntityContainerAttribute = "IsDefaultEntityContainer"; - - internal const string ServiceOperationHttpMethodName = "HttpMethod"; - - internal const string UriElementName = "uri"; - - internal const string NextElementName = "next"; - - internal const string LinkCollectionElementName = "links"; - - #endregion DataWeb Elements and Attributes. - - #region JSON Format constants - - internal const string JsonError = "error"; - - internal const string JsonErrorCode = "code"; - - internal const string JsonErrorInner = "innererror"; - - internal const string JsonErrorInternalException = "internalexception"; - - internal const string JsonErrorMessage = "message"; - - internal const string JsonErrorStackTrace = "stacktrace"; - - internal const string JsonErrorType = "type"; - - internal const string JsonErrorValue = "value"; - - internal const string JsonMetadataString = "__metadata"; - - internal const string JsonUriString = "uri"; - - internal const string JsonTypeString = "type"; - - internal const string JsonEditMediaString = "edit_media"; - - internal const string JsonMediaSrcString = "media_src"; - - internal const string JsonContentTypeString = "content_type"; - - internal const string JsonMediaETagString = "media_etag"; - - internal const string JsonDeferredString = "__deferred"; - - internal const string JsonETagString = "etag"; - - internal const string JsonRowCountString = "__count"; - - internal const string JsonNextString = "__next"; - - #endregion //JSON Format constants - - #region Edm Primitive Type Names - internal const string EdmNamespace = "Edm"; - - internal const string EdmBinaryTypeName = "Edm.Binary"; - - internal const string EdmBooleanTypeName = "Edm.Boolean"; - - internal const string EdmByteTypeName = "Edm.Byte"; - - internal const string EdmDateTimeTypeName = "Edm.DateTime"; - - internal const string EdmDecimalTypeName = "Edm.Decimal"; - - internal const string EdmDoubleTypeName = "Edm.Double"; - - internal const string EdmGuidTypeName = "Edm.Guid"; - - internal const string EdmSingleTypeName = "Edm.Single"; - - internal const string EdmSByteTypeName = "Edm.SByte"; - - internal const string EdmInt16TypeName = "Edm.Int16"; - - internal const string EdmInt32TypeName = "Edm.Int32"; - - internal const string EdmInt64TypeName = "Edm.Int64"; - - internal const string EdmStringTypeName = "Edm.String"; - #endregion - - #region Astoria Constants - - internal const string DataServiceVersion1Dot0 = "1.0"; - - internal const string DataServiceVersion2Dot0 = "2.0"; - - internal const string DataServiceVersionCurrent = DataServiceVersion2Dot0 + ";"; - - internal const int DataServiceVersionCurrentMajor = 1; - - internal const int DataServiceVersionCurrentMinor = 0; - - internal const string LiteralPrefixBinary = "binary"; - - internal const string LiteralPrefixDateTime = "datetime"; - - internal const string LiteralPrefixGuid = "guid"; - - internal const string XmlBinaryPrefix = "X"; - - internal const string XmlDecimalLiteralSuffix = "M"; - - internal const string XmlInt64LiteralSuffix = "L"; - - internal const string XmlSingleLiteralSuffix = "f"; - - internal const string XmlDoubleLiteralSuffix = "D"; - - internal const string NullLiteralInETag = "null"; - - internal const string MicrosoftDataServicesRequestUri = "MicrosoftDataServicesRequestUri"; - - internal const string MicrosoftDataServicesRootUri = "MicrosoftDataServicesRootUri"; - - #endregion - - #region EF constants - - internal const string StoreGeneratedPattern = "http://schemas.microsoft.com/ado/2006/04/edm/ssdl:StoreGeneratedPattern"; - #endregion //EF constants - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePermissions.cs deleted file mode 100644 index 51e68bf4ba714..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePermissions.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - - /// - /// Specifies the set of possible permissions for a shared access table policy. - /// - [Flags] - public enum SharedAccessTablePermissions - { - /// - /// No shared access granted. - /// - None = 0x0, - - /// - /// Permission to query entities granted. - /// - Query = 0x1, - - /// - /// Permission to add entities granted. - /// - Add = 0x2, - - /// - /// Permission to modify entities granted. - /// - Update = 0x4, - - /// - /// Permission to delete entities granted. - /// - Delete = 0x8 - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicies.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicies.cs deleted file mode 100644 index bedce242e7e93..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicies.cs +++ /dev/null @@ -1,216 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents the collection of shared access policies defined for a table. - /// - [SuppressMessage( - "Microsoft.Naming", - "CA1710:IdentifiersShouldHaveCorrectSuffix", - Justification = "Public APIs should not expose base collection types.")] - public sealed class SharedAccessTablePolicies : IDictionary - { - private readonly Dictionary policies = - new Dictionary(); - - /// - /// Adds the specified key and value to the collection of shared access policies. - /// - /// The key of the value to add. - /// The value to add to the collection of shared access policies. - public void Add(string key, SharedAccessTablePolicy value) - { - this.policies.Add(key, value); - } - - /// - /// Determines whether the collection of shared access policies contains the specified key. - /// - /// The key to locate in the collection of shared access policies. - /// true if the collection of shared access policies contains an element with the specified key; otherwise, false. - public bool ContainsKey(string key) - { - return this.policies.ContainsKey(key); - } - - /// - /// Gets a collection containing the keys in the shared access policies collection. - /// - /// A collection containing the keys in the of shared access policies collection. - public ICollection Keys - { - get { return this.policies.Keys; } - } - - /// - /// Removes the value with the specified key from the shared access policies collection. - /// - /// The key of the item to remove. - /// true if the element is successfully found and removed; otherwise, false. This method returns false if the key is not found. - public bool Remove(string key) - { - return this.policies.Remove(key); - } - - /// - /// Gets the item associated with the specified key. - /// - /// The key of the value to get. - /// The item to get. - /// The item associated with the specified key, if the key is found; otherwise, the default value for the type. - public bool TryGetValue(string key, out SharedAccessTablePolicy value) - { - return this.policies.TryGetValue(key, out value); - } - - /// - /// Gets a collection containing the values in the shared access policies collection. - /// - /// A collection of items in the shared access policies collection. - public ICollection Values - { - get { return this.policies.Values; } - } - - /// - /// Gets or sets the item associated with the specified key. - /// - /// The key of the value to get or set. - /// The item associated with the specified key, or null if key is not in the shared access policies collection. - public SharedAccessTablePolicy this[string key] - { - get { return this.policies[key]; } - - set { this.policies[key] = value; } - } - - /// - /// Adds the specified key/ value, stored in a , to the collection of shared access policies. - /// - /// The object, containing a key/ value pair, to add to the shared access policies collection. - public void Add(KeyValuePair item) - { - this.Add(item.Key, item.Value); - } - - /// - /// Removes all keys and values from the shared access collection. - /// - public void Clear() - { - this.policies.Clear(); - } - - /// - /// Determines whether the collection of shared access policies contains the key and value in the specified object. - /// - /// A object containing the key and value to search for. - /// true if the shared access policies collection contains the specified key/value; otherwise, false. - public bool Contains(KeyValuePair item) - { - SharedAccessTablePolicy storedItem; - if (this.TryGetValue(item.Key, out storedItem)) - { - if (string.Equals( - SharedAccessTablePolicy.PermissionsToString(item.Value.Permissions), - SharedAccessTablePolicy.PermissionsToString(storedItem.Permissions), - StringComparison.Ordinal)) - { - return true; - } - } - - return false; - } - - /// - /// Copies each key/ value pair in the shared access policies collection to a compatible one-dimensional array, starting at the specified index of the target array. - /// - /// The one-dimensional array of objects that is the destination of the elements copied from the shared access policies collection. - /// The zero-based index in at which copying begins. - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - CommonUtility.AssertNotNull("array", array); - - foreach (KeyValuePair item in this.policies) - { - array[arrayIndex++] = item; - } - } - - /// - /// Gets the number of key/ value pairs contained in the shared access policies collection. - /// - /// The number of key/ value pairs contained in the shared access policies collection. - public int Count - { - get { return this.policies.Count; } - } - - /// - /// Gets a value indicating whether the collection of shared access policies is read-only. - /// - /// true if the collection of shared access policies is read-only; otherwise, false. - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Removes the value, specified in the object, from the shared access policies collection. - /// - /// The object, containing a key and value, to remove from the shared access policies collection. - /// true if the item was successfully removed; otherwise, false. - public bool Remove(KeyValuePair item) - { - if (this.Contains(item)) - { - return this.Remove(item.Key); - } - else - { - return false; - } - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An of type . - public IEnumerator> GetEnumerator() - { - return this.policies.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through the collection of shared access policies. - /// - /// An object that can be used to iterate through the collection of shared access policies. - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - System.Collections.IEnumerable enumerable = this.policies; - return enumerable.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicy.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicy.cs deleted file mode 100644 index 52a1f49f1649a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/SharedAccessTablePolicy.cs +++ /dev/null @@ -1,133 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Text; - - /// - /// Represents a shared access policy, which specifies the start time, expiry time, - /// and permissions for a shared access signature. - /// - public sealed class SharedAccessTablePolicy - { - /// - /// Initializes a new instance of the SharedAccessTablePolicy class. - /// - public SharedAccessTablePolicy() - { - } - - /// - /// Gets or sets the start time for a shared access signature associated with this shared access policy. - /// - /// The shared access start time. - public DateTimeOffset? SharedAccessStartTime { get; set; } - - /// - /// Gets or sets the expiry time for a shared access signature associated with this shared access policy. - /// - /// The shared access expiry time. - public DateTimeOffset? SharedAccessExpiryTime { get; set; } - - /// - /// Gets or sets the permissions for a shared access signature associated with this shared access policy. - /// - /// The permissions. - public SharedAccessTablePermissions Permissions { get; set; } - - /// - /// Converts the permissions specified for the shared access policy to a string. - /// - /// The shared access permissions. - /// The shared access permissions in string format. - public static string PermissionsToString(SharedAccessTablePermissions permissions) - { - // The service supports a fixed order => raud - StringBuilder builder = new StringBuilder(); - - if ((permissions & SharedAccessTablePermissions.Query) == SharedAccessTablePermissions.Query) - { - builder.Append("r"); - } - - if ((permissions & SharedAccessTablePermissions.Add) == SharedAccessTablePermissions.Add) - { - builder.Append("a"); - } - - if ((permissions & SharedAccessTablePermissions.Update) == SharedAccessTablePermissions.Update) - { - builder.Append("u"); - } - - if ((permissions & SharedAccessTablePermissions.Delete) == SharedAccessTablePermissions.Delete) - { - builder.Append("d"); - } - - return builder.ToString(); - } - - /// - /// Constructs a object from a permissions string. - /// - /// The shared access permissions in string format. - /// A set of shared access permissions. - public static SharedAccessTablePermissions PermissionsFromString(string input) - { - CommonUtility.AssertNotNull("input", input); - - SharedAccessTablePermissions permissions = 0; - - foreach (char c in input) - { - switch (c) - { - case 'r': - permissions |= SharedAccessTablePermissions.Query; - break; - - case 'a': - permissions |= SharedAccessTablePermissions.Add; - break; - - case 'u': - permissions |= SharedAccessTablePermissions.Update; - break; - - case 'd': - permissions |= SharedAccessTablePermissions.Delete; - break; - - default: - throw new ArgumentOutOfRangeException("input"); - } - } - - // Incase we ever change none to be something other than 0 - if (permissions == 0) - { - permissions |= SharedAccessTablePermissions.None; - } - - return permissions; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableBatchOperation.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableBatchOperation.Common.cs deleted file mode 100644 index 13c5a1d9edd4b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableBatchOperation.Common.cs +++ /dev/null @@ -1,355 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - - /// - /// Represents a batch operation on a table. - /// - /// 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.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 total payload of a batch operation is limited to 4MB. - public sealed partial class TableBatchOperation : IList - { - private bool hasQuery = false; - private string batchPartitionKey = null; - private List operations = new List(); - - /// - /// Initializes a new instance of the class. - /// - public TableBatchOperation() - { - } - - #region Operation Factories - - /// - /// Adds a to the that deletes the specified entity from a table. - /// - /// The entity to be deleted from the table. - public void Delete(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Delete requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForDelete); - } - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.Delete)); - } - - /// - /// Adds a to the that inserts the specified entity into a table. - /// - /// The entity to be inserted into the table. - public void Insert(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.Insert)); - } - - /// - /// Adds a to the that inserts the specified entity into a table if the entity does not exist; if the entity does exist then its contents are merged with the provided entity. - /// - /// The entity whose contents are being inserted or merged. - public void InsertOrMerge(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.InsertOrMerge)); - } - - /// - /// Adds a to the that inserts the specified entity into a table if the entity does not exist; if the entity does exist then its contents are replaced with the provided entity. - /// - /// The entity whose contents are being inserted or replaced. - public void InsertOrReplace(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.InsertOrReplace)); - } - - /// - /// Adds a to the that merges the contents of the specified entity with the existing entity in a table. - /// - /// The entity whose contents are being merged. - public void Merge(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Merge requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForMerge); - } - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.Merge)); - } - - /// - /// Adds a to the that replaces the contents of the specified entity in a table. - /// - /// The entity whose contents are being replaced. - public void Replace(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Replace requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForReplace); - } - - // Add the table operation. - this.Add(new TableOperation(entity, TableOperationType.Replace)); - } - - /// - /// Adds a to the that retrieves an entity with the specified partition key and row key. - /// - /// A string containing the partition key of the entity to retrieve. - /// A string containing the row key of the entity to retrieve. - public void Retrieve(string partitionKey, string rowKey) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowKey); - - // Add the table operation. - this.Add(new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowKey }); - } - #endregion - - #region IList - - /// - /// Returns the zero-based index of the first occurrence of the specified item, or -1 if the does not contain the item. - /// - /// The item to search for. - /// The zero-based index of the first occurrence of item within the , if found; otherwise, –1. - public int IndexOf(TableOperation item) - { - return this.operations.IndexOf(item); - } - - /// - /// Inserts a into the at the specified index. - /// - /// The index at which to insert the . - /// The item to insert. - public void Insert(int index, TableOperation item) - { - CommonUtility.AssertNotNull("item", item); - this.CheckSingleQueryPerBatch(item); - this.LockToPartitionKey(item.OperationType == TableOperationType.Retrieve ? item.RetrievePartitionKey : item.Entity.PartitionKey); - - this.operations.Insert(index, item); - } - - /// - /// Removes the at the specified index from the . - /// - /// The index of the to remove from the . - public void RemoveAt(int index) - { - this.operations.RemoveAt(index); - - if (this.operations.Count == 0) - { - this.batchPartitionKey = null; - this.hasQuery = false; - } - } - - /// - /// Gets or sets the item at the specified index. - /// - /// The index at which to get or set the item. - /// The item at the specified index. - public TableOperation this[int index] - { - get - { - return this.operations[index]; - } - - set - { - throw new NotSupportedException(); - } - } - - /// - /// Adds the to the . - /// - /// The item to add to the . - public void Add(TableOperation item) - { - CommonUtility.AssertNotNull("item", item); - this.CheckSingleQueryPerBatch(item); - this.LockToPartitionKey(item.OperationType == TableOperationType.Retrieve ? item.RetrievePartitionKey : item.Entity.PartitionKey); - - this.operations.Add(item); - } - - /// - /// Clears all objects from the . - /// - public void Clear() - { - this.operations.Clear(); - this.batchPartitionKey = null; - this.hasQuery = false; - } - - /// - /// Returns true if this contains the specified element. - /// - /// The item to search for. - /// true if the item is contained in the ; false, otherwise. - public bool Contains(TableOperation item) - { - return this.operations.Contains(item); - } - - /// - /// Copies all the elements of the to the specified one-dimensional array starting at the specified destination array index. - /// - /// The one-dimensional array that is the destination of the elements copied from the . - /// The index in the destination array at which copying begins. - public void CopyTo(TableOperation[] array, int arrayIndex) - { - this.operations.CopyTo(array, arrayIndex); - } - - /// - /// Gets the number of operations in this . - /// - /// The number of operations in the . - public int Count - { - get { return this.operations.Count; } - } - - /// - /// Gets a value indicating whether the is read-only. - /// - /// true if the is read-only; false, otherwise. - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Removes the specified item from the . - /// - /// The item to remove. - /// true if the item was successfully removed; false, otherwise. - public bool Remove(TableOperation item) - { - CommonUtility.AssertNotNull("item", item); - - bool retVal = this.operations.Remove(item); - - if (this.operations.Count == 0) - { - this.batchPartitionKey = null; - this.hasQuery = false; - } - - return retVal; - } - - /// - /// Returns an for the . - /// - /// An enumerable collection of items. - public IEnumerator GetEnumerator() - { - return this.operations.GetEnumerator(); - } - - /// - /// Returns an . - /// - /// An for the . - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.operations.GetEnumerator(); - } - #endregion - - #region Private Validators - private void CheckSingleQueryPerBatch(TableOperation item) - { - if (this.hasQuery) - { - throw new ArgumentException(SR.BatchWithRetreiveContainsOtherOperations); - } - - if (item.OperationType == TableOperationType.Retrieve) - { - if (this.operations.Count > 0) - { - throw new ArgumentException(SR.BatchWithRetreiveContainsOtherOperations); - } - else - { - this.hasQuery = true; - } - } - } - - private void LockToPartitionKey(string partitionKey) - { - if (this.batchPartitionKey == null) - { - this.batchPartitionKey = partitionKey; - } - else - { - if (partitionKey != this.batchPartitionKey) - { - throw new ArgumentException(SR.PartitionKey); - } - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableContinuationToken.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableContinuationToken.cs deleted file mode 100644 index 694ac5ff6c970..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableContinuationToken.cs +++ /dev/null @@ -1,199 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Xml; - using System.Xml.Schema; - using System.Xml.Serialization; - - /// - /// Represents a continuation token for listing operations. - /// - /// A method that may return a partial set of results via a object also returns a continuation token, - /// which can be used in a subsequent call to return the next set of available results. -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - [Serializable] -#endif - [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1001:CommasMustBeSpacedCorrectly", Justification = "Reviewed.")] - public sealed class TableContinuationToken : IContinuationToken -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - , IXmlSerializable -#endif - { - /// - /// Gets or sets the next partition key for enumeration operations. - /// - /// The next partition key. - public string NextPartitionKey { get; set; } - - /// - /// Gets or sets the next row key for enumeration operations. - /// - /// The next row key. - public string NextRowKey { get; set; } - - /// - /// Gets or sets the next table name for enumeration operations. - /// - /// The name of the next table. - public string NextTableName { get; set; } - -#if !WINDOWS_RT - /// - /// Gets an XML representation of an object. - /// - /// - /// An that describes the XML representation of the object that is produced by the method and consumed by the method. - /// - public XmlSchema GetSchema() - { - return null; - } - - /// - /// Generates a serializable continuation token from its XML representation. - /// - /// The stream from which the continuation token is deserialized. - public void ReadXml(XmlReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - reader.MoveToContent(); - - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - reader.ReadStartElement(); - while (reader.IsStartElement()) - { - if (reader.IsEmptyElement) - { - reader.Skip(); - } - else - { - switch (reader.Name) - { - case Constants.ContinuationConstants.VersionElement: - string version = reader.ReadElementContentAsString(); - if (version != Constants.ContinuationConstants.CurrentVersion) - { - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, version)); - } - - break; - - case Constants.ContinuationConstants.NextPartitionKeyElement: - this.NextPartitionKey = reader.ReadElementContentAsString(); - break; - - case Constants.ContinuationConstants.NextRowKeyElement: - this.NextRowKey = reader.ReadElementContentAsString(); - break; - - case Constants.ContinuationConstants.NextTableNameElement: - this.NextTableName = reader.ReadElementContentAsString(); - break; - - case Constants.ContinuationConstants.TypeElement: - string continuationType = reader.ReadElementContentAsString(); - if (Constants.ContinuationConstants.TableType != continuationType) - { - throw new XmlException(SR.UnexpectedContinuationType); - } - - break; - - default: - throw new XmlException(string.Format(CultureInfo.InvariantCulture, SR.UnexpectedElement, reader.Name)); - } - } - } - - reader.ReadEndElement(); - } - } - - /// - /// Converts a serializable continuation token into its XML representation. - /// - /// The stream to which the continuation token is serialized. - public void WriteXml(XmlWriter writer) - { - if (writer == null) - { - throw new ArgumentNullException("writer"); - } - - writer.WriteStartElement(Constants.ContinuationConstants.ContinuationTopElement); - - writer.WriteElementString(Constants.ContinuationConstants.VersionElement, Constants.ContinuationConstants.CurrentVersion); - - writer.WriteElementString(Constants.ContinuationConstants.TypeElement, Constants.ContinuationConstants.TableType); - - if (this.NextPartitionKey != null) - { - writer.WriteElementString(Constants.ContinuationConstants.NextPartitionKeyElement, this.NextPartitionKey); - } - - if (this.NextRowKey != null) - { - writer.WriteElementString(Constants.ContinuationConstants.NextRowKeyElement, this.NextRowKey); - } - - if (this.NextTableName != null) - { - writer.WriteElementString(Constants.ContinuationConstants.NextTableNameElement, this.NextTableName); - } - - writer.WriteEndElement(); // End ContinuationToken - } -#endif - - internal void ApplyToUriQueryBuilder(UriQueryBuilder builder) - { - if (!string.IsNullOrEmpty(this.NextPartitionKey)) - { - builder.Add(TableConstants.TableServiceNextPartitionKey, this.NextPartitionKey); - } - - if (!string.IsNullOrEmpty(this.NextRowKey)) - { - builder.Add(TableConstants.TableServiceNextRowKey, this.NextRowKey); - } - - if (!string.IsNullOrEmpty(this.NextTableName)) - { - builder.Add(TableConstants.TableServiceNextTableName, this.NextTableName); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableEntity.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableEntity.cs deleted file mode 100644 index 9398147a90b4b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableEntity.cs +++ /dev/null @@ -1,756 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Reflection; - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - using ReadAction = System.Action>; - using WriteFunc = System.Func>; - using System.Linq; - using System.Linq.Expressions; - using System.Collections.Concurrent; - -#endif - - /// - /// Represents the base object type for a table entity in the Table service. - /// - /// provides a base implementation for the interface that provides and methods that by default serialize and - /// deserialize all properties via reflection. A table entity class may extend this class and override the and methods to provide customized or better performing serialization logic. - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1114:ParameterListMustFollowDeclaration", Justification = "Reviewed.")] - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1115:ParameterMustFollowComma", Justification = "Reviewed.")] - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1116:SplitParametersMustStartOnLineAfterDeclaration", Justification = "Reviewed.")] - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:ParametersMustBeOnSameLineOrSeparateLines", Justification = "Reviewed.")] - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:ParameterMustNotSpanMultipleLines", Justification = "Reviewed.")] - public class TableEntity : ITableEntity - { -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - static TableEntity() - { - DisableCompiledSerializers = false; - } -#endif - - /// - /// Initializes a new instance of the class. - /// - public TableEntity() - { - } - - /// - /// Initializes a new instance of the class with the specified partition key and row key. - /// - /// The partition key of the to be initialized. - /// The row key of the to be initialized. - public TableEntity(string partitionKey, string rowKey) - { - this.PartitionKey = partitionKey; - this.RowKey = rowKey; - } - - #region ITableEntity Implementation - - /// - /// Gets or sets the entity's partition key. - /// - /// The partition key of the entity. - public string PartitionKey { get; set; } - - /// - /// Gets or sets the entity's row key. - /// - /// The row key of the entity. - public string RowKey { get; set; } - - /// - /// Gets or sets the entity's timestamp. - /// - /// The timestamp of the entity. - public DateTimeOffset Timestamp { get; set; } - - /// - /// Gets or sets the entity's current ETag. Set this value to '*' in order to blindly overwrite an entity as part of an update operation. - /// - /// The ETag of the entity. - public string ETag { get; set; } - - /// - /// Deserializes this instance using the specified of property names to data typed values. - /// - /// The map of string property names to data values to deserialize and store in this table entity instance. - /// An object used to track the execution of the operation. - public virtual void ReadEntity(IDictionary properties, OperationContext operationContext) - { -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - if (!TableEntity.DisableCompiledSerializers) - { - if (this.CompiledRead == null) - { - this.CompiledRead = compiledReadCache.GetOrAdd(this.GetType(), TableEntity.CompileReadAction); - } - - this.CompiledRead(this, operationContext, properties); - return; - } -#endif - ReflectionRead(this, properties, operationContext); - } - - /// - /// Deserializes a custom entity instance using the specified of property names to data typed values. - /// - /// Custom entity instance being deserialized. - /// The map of string property names to data values to deserialize and store in this entity instance. - /// An object used to track the execution of the operation. - public static void ReadUserObject(object entity, IDictionary properties, OperationContext operationContext) - { - CommonUtility.AssertNotNull("entity", entity); - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - if (!TableEntity.DisableCompiledSerializers) - { - ReadAction compiledReadAction = compiledReadCache.GetOrAdd(entity.GetType(), TableEntity.CompileReadAction); - compiledReadAction(entity, operationContext, properties); - return; - } -#endif - ReflectionRead(entity, properties, operationContext); - } - - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1121:UseBuiltInTypeAlias", Justification = "Needed for object type checking.")] - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Reviewed")] - private static void ReflectionRead(object entity, IDictionary properties, OperationContext operationContext) - { -#if WINDOWS_RT - IEnumerable objectProperties = entity.GetType().GetRuntimeProperties(); -#else - IEnumerable objectProperties = entity.GetType().GetProperties(); -#endif - foreach (PropertyInfo property in objectProperties) - { - if (ShouldSkipProperty(property, operationContext)) - { - continue; - } - - // only proceed with properties that have a corresponding entry in the dictionary - if (!properties.ContainsKey(property.Name)) - { - Logger.LogInformational(operationContext, SR.TraceMissingDictionaryEntry, property.Name); - continue; - } - - EntityProperty entityProperty = properties[property.Name]; - - if (entityProperty.IsNull) - { - property.SetValue(entity, null, null); - } - else - { - switch (entityProperty.PropertyType) - { - case EdmType.String: - if (property.PropertyType != typeof(string)) - { - continue; - } - - property.SetValue(entity, entityProperty.StringValue, null); - break; - case EdmType.Binary: - if (property.PropertyType != typeof(byte[])) - { - continue; - } - - property.SetValue(entity, entityProperty.BinaryValue, null); - break; - case EdmType.Boolean: - if (property.PropertyType != typeof(bool) && property.PropertyType != typeof(bool?)) - { - continue; - } - - property.SetValue(entity, entityProperty.BooleanValue, null); - break; - case EdmType.DateTime: - if (property.PropertyType == typeof(DateTime)) - { - property.SetValue(entity, entityProperty.DateTimeOffsetValue.Value.UtcDateTime, null); - } - else if (property.PropertyType == typeof(DateTime?)) - { - property.SetValue(entity, entityProperty.DateTimeOffsetValue.HasValue ? entityProperty.DateTimeOffsetValue.Value.UtcDateTime : (DateTime?)null, null); - } - else if (property.PropertyType == typeof(DateTimeOffset)) - { - property.SetValue(entity, entityProperty.DateTimeOffsetValue.Value, null); - } - else if (property.PropertyType == typeof(DateTimeOffset?)) - { - property.SetValue(entity, entityProperty.DateTimeOffsetValue, null); - } - - break; - case EdmType.Double: - if (property.PropertyType != typeof(double) && property.PropertyType != typeof(double?)) - { - continue; - } - - property.SetValue(entity, entityProperty.DoubleValue, null); - break; - case EdmType.Guid: - if (property.PropertyType != typeof(Guid) && property.PropertyType != typeof(Guid?)) - { - continue; - } - - property.SetValue(entity, entityProperty.GuidValue, null); - break; - case EdmType.Int32: - if (property.PropertyType != typeof(int) && property.PropertyType != typeof(int?)) - { - continue; - } - - property.SetValue(entity, entityProperty.Int32Value, null); - break; - case EdmType.Int64: - if (property.PropertyType != typeof(long) && property.PropertyType != typeof(long?)) - { - continue; - } - - property.SetValue(entity, entityProperty.Int64Value, null); - break; - } - } - } - } - - /// - /// Serializes the of property names mapped to data values from this instance. - /// - /// An object used to track the execution of the operation. - /// A map of property names to data typed values created by serializing this table entity instance. - public virtual IDictionary WriteEntity(OperationContext operationContext) - { -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - if (!TableEntity.DisableCompiledSerializers) - { - if (this.CompiledWrite == null) - { - this.CompiledWrite = compiledWriteCache.GetOrAdd(this.GetType(), TableEntity.CompileWriteFunc); - } - - return this.CompiledWrite(this, operationContext); - } -#endif - return ReflectionWrite(this, operationContext); - } - - /// - /// Create a of objects for all the properties of the specified entity object. - /// - /// The entity object to serialize. - /// An object used to track the execution of the operation. - /// A of objects for all the properties of the specified entity object. - public static IDictionary WriteUserObject(object entity, OperationContext operationContext) - { - CommonUtility.AssertNotNull("entity", entity); - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - if (!TableEntity.DisableCompiledSerializers) - { - WriteFunc compiledWriteAction = compiledWriteCache.GetOrAdd(entity.GetType(), TableEntity.CompileWriteFunc); - return compiledWriteAction(entity, operationContext); - } -#endif - return ReflectionWrite(entity, operationContext); - } - - private static IDictionary ReflectionWrite(object entity, OperationContext operationContext) - { - Dictionary retVals = new Dictionary(); - -#if WINDOWS_RT - IEnumerable objectProperties = entity.GetType().GetRuntimeProperties(); -#else - IEnumerable objectProperties = entity.GetType().GetProperties(); -#endif - - foreach (PropertyInfo property in objectProperties) - { - if (ShouldSkipProperty(property, operationContext)) - { - continue; - } - - EntityProperty newProperty = EntityProperty.CreateEntityPropertyFromObject(property.GetValue(entity, null), property.PropertyType); - - // property will be null if unknown type - if (newProperty != null) - { - retVals.Add(property.Name, newProperty); - } - } - - return retVals; - } - - #endregion - - #region Static Helpers - /// - /// Determines if the given property should be skipped based on its name, if it exposes a public getter and setter, and if the IgnoreAttribute is not defined. - /// - /// The PropertyInfo of the property to check - /// An object used to track the execution of the operation. - /// True if the property should be skipped, false otherwise. - private static bool ShouldSkipProperty(PropertyInfo property, OperationContext operationContext) - { - // reserved properties - string propName = property.Name; - if (propName == TableConstants.PartitionKey || - propName == TableConstants.RowKey || - propName == TableConstants.Timestamp || - propName == TableConstants.Etag) - { - return true; - } - - MethodInfo setter = property.FindSetProp(); - MethodInfo getter = property.FindGetProp(); - - // Enforce public getter / setter - if (setter == null || !setter.IsPublic || getter == null || !getter.IsPublic) - { - Logger.LogInformational(operationContext, SR.TraceNonPublicGetSet, property.Name); - return true; - } - - // Skip static properties - if (setter.IsStatic) - { - return true; - } - - // properties with [IgnoreAttribute] -#if WINDOWS_RT - if (property.GetCustomAttribute(typeof(IgnorePropertyAttribute)) != null) -#else - if (Attribute.IsDefined(property, typeof(IgnorePropertyAttribute))) -#endif - { - Logger.LogInformational(operationContext, SR.TraceIgnoreAttribute, property.Name); - return true; - } - - return false; - } - #endregion - - #region CompiledSerialization Logic - -#if WINDOWS_DESKTOP && !WINDOWS_PHONE - private static void ReadNoOpAction(object obj, OperationContext ctx, IDictionary dict) - { - // no op - } - - private static IDictionary WriteNoOpFunc(object obj, OperationContext ctx) - { - return new Dictionary(); - } - - private static MethodInfo GetKeyOrNullFromDictionaryMethodInfo { get; set; } - - private static MethodInfo DictionaryAddMethodInfo { get; set; } - - private static MethodInfo EntityProperty_CreateFromObjectMethodInfo { get; set; } - - private static MethodInfo EntityPropertyIsNullInfo { get; set; } - - private static PropertyInfo EntityPropertyPropTypePInfo { get; set; } - - private static PropertyInfo EntityProperty_StringPI { get; set; } - - private static PropertyInfo EntityProperty_BinaryPI { get; set; } - - private static PropertyInfo EntityProperty_BoolPI { get; set; } - - private static PropertyInfo EntityProperty_DateTimeOffsetPI { get; set; } - - private static PropertyInfo EntityProperty_DoublePI { get; set; } - - private static PropertyInfo EntityProperty_GuidPI { get; set; } - - private static PropertyInfo EntityProperty_Int32PI { get; set; } - - private static PropertyInfo EntityProperty_Int64PI { get; set; } - - private static PropertyInfo EntityProperty_PropTypePI { get; set; } - - private static MethodInfo EntityProperty_PropTypeGetter { get; set; } - - private static ConcurrentDictionary compiledWriteCache = new ConcurrentDictionary(); - - private static ConcurrentDictionary compiledReadCache = new ConcurrentDictionary(); - - /// - /// Disables the ability to dynamically generate read and write lambdas at runtime. Setting this to false will clear out the static cache shared across all type instances that derive from TableEntity. - /// - public static bool DisableCompiledSerializers - { - get - { - return disableCompiledSerializers; - } - - set - { - if (value) - { - // Disabled, clear all dictionaries - compiledReadCache.Clear(); - compiledWriteCache.Clear(); - } - else if (EntityProperty_CreateFromObjectMethodInfo == null) - { - // Only do reflection once - EntityProperty_CreateFromObjectMethodInfo = typeof(EntityProperty).FindStaticMethods("CreateEntityPropertyFromObject").First((m) => - { - ParameterInfo[] mParams = m.GetParameters(); - return mParams.Length == 2 && mParams[0].ParameterType == typeof(object) && mParams[1].ParameterType == typeof(Type); - }); - - GetKeyOrNullFromDictionaryMethodInfo = typeof(TableEntity).FindStaticMethods("GetValueByKeyFromDictionary").First((m) => m.GetParameters().Length == 3); - DictionaryAddMethodInfo = typeof(Dictionary).FindMethod("Add", new Type[] { typeof(string), typeof(EntityProperty) }); - EntityProperty_StringPI = typeof(EntityProperty).FindProperty("StringValue"); - EntityProperty_BinaryPI = typeof(EntityProperty).FindProperty("BinaryValue"); - EntityProperty_BoolPI = typeof(EntityProperty).FindProperty("BooleanValue"); - EntityProperty_DateTimeOffsetPI = typeof(EntityProperty).FindProperty("DateTimeOffsetValue"); - EntityProperty_DoublePI = typeof(EntityProperty).FindProperty("DoubleValue"); - EntityProperty_GuidPI = typeof(EntityProperty).FindProperty("GuidValue"); - EntityProperty_Int32PI = typeof(EntityProperty).FindProperty("Int32Value"); - EntityProperty_Int64PI = typeof(EntityProperty).FindProperty("Int64Value"); - EntityProperty_PropTypePI = typeof(EntityProperty).FindProperty("PropertyType"); - EntityProperty_PropTypeGetter = EntityProperty_PropTypePI.FindGetProp(); - -#if WINDOWS_RT - EntityPropertyIsNullInfo = typeof(EntityProperty).GetRuntimeProperties().First((m) => m.Name == "IsNull").GetMethod; -#else - EntityPropertyIsNullInfo = typeof(EntityProperty).FindProperty("IsNull").GetGetMethod(true); -#endif - } - - disableCompiledSerializers = value; - } - } - - private static volatile bool disableCompiledSerializers = false; - - /// - /// This entities compiled Write Func - /// - internal WriteFunc CompiledWrite { get; set; } - - /// - /// This entities compiled Read Action - /// - internal ReadAction CompiledRead { get; set; } - - /// - /// Compiles a ReadAction for the given type - /// - /// The type to compile for - /// A ReadAction that deserializes the given entity type. - private static ReadAction CompileReadAction(Type type) - { -#if WINDOWS_RT - IEnumerable objectProperties = type.GetRuntimeProperties(); -#else - IEnumerable objectProperties = type.GetProperties(); -#endif - ParameterExpression instanceParam = Expression.Parameter(typeof(object), "instance"); - ParameterExpression ctxParam = Expression.Parameter(typeof(OperationContext), "ctx"); - ParameterExpression dictVariable = Expression.Parameter(typeof(IDictionary), "dict"); - ParameterExpression tempProp = Expression.Variable(typeof(EntityProperty), "entityProp"); - ParameterExpression propName = Expression.Variable(typeof(string), "propName"); - - List exprs = new List(); - foreach (PropertyInfo prop in objectProperties.Where(p => !ShouldSkipProperty(p, null /* OperationContext */))) - { - Expression readExpr = GeneratePropertyReadExpressionByType(type, prop, instanceParam, tempProp); - - if (readExpr != null) - { - exprs.Add(Expression.Assign(propName, Expression.Constant(prop.Name))); - exprs.Add(Expression.Assign(tempProp, Expression.Call(GetKeyOrNullFromDictionaryMethodInfo, propName, dictVariable, ctxParam))); - - exprs.Add( - - // If property is not null - Expression.IfThen(Expression.NotEqual(tempProp, Expression.Constant(null)), - - // then if prop.Isnull, objProp.SetValue(null) - Expression.IfThenElse(Expression.Call(tempProp, EntityPropertyIsNullInfo), - - // then - Expression.Call(Expression.Convert(instanceParam, type), prop.FindSetProp(), Expression.Convert(Expression.Constant(null), prop.PropertyType)), - - // else set entity property based on type - readExpr))); - } - } - - // If no additional property expressions were added return a no op lambda - if (exprs.Count == 0) - { - return TableEntity.ReadNoOpAction; - } - - var lambda = Expression.Lambda>>( - Expression.Block(new[] { tempProp, propName }, exprs), - new[] { instanceParam, ctxParam, dictVariable }); - - return lambda.Compile(); - } - - /// - /// Compiles a WriteFunc for the given type - /// - /// The type to compile for - /// A WriteFunc that serializes the given entity type. - private static WriteFunc CompileWriteFunc(Type type) - { -#if WINDOWS_RT - IEnumerable objectProperties = type.GetRuntimeProperties(); -#else - IEnumerable objectProperties = type.GetProperties(); -#endif - ParameterExpression instanceParam = Expression.Parameter(typeof(object), "instance"); - ParameterExpression ctxParam = Expression.Parameter(typeof(OperationContext), "ctx"); - ParameterExpression tempProp = Expression.Variable(typeof(EntityProperty), "entityProp"); - ParameterExpression propName = Expression.Variable(typeof(string), "propName"); - ParameterExpression dictVar = Expression.Variable(typeof(Dictionary), "dictVar"); - - List exprs = new List(); - - // Dict = new Dictionary(); - exprs.Add(Expression.Assign(dictVar, Expression.New(typeof(Dictionary)))); - - foreach (PropertyInfo prop in objectProperties.Where(p => !ShouldSkipProperty(p, null /* OperationContext */))) - { - exprs.Add(Expression.Assign(tempProp, Expression.Call(EntityProperty_CreateFromObjectMethodInfo, - Expression.Convert(Expression.Call(Expression.Convert(instanceParam, type), prop.FindGetProp()), typeof(object)), - Expression.Constant(prop.PropertyType)))); - - exprs.Add(Expression.Assign(propName, Expression.Constant(prop.Name))); - - // if tempprop!=null dict.Add(propName, Prop); - exprs.Add(Expression.IfThen(Expression.NotEqual(tempProp, Expression.Constant(null)), Expression.Call(dictVar, DictionaryAddMethodInfo, propName, tempProp))); - } - - // If no additional property expressions were added return a no op lambda - if (exprs.Count == 1) - { - return TableEntity.WriteNoOpFunc; - } - - // return dictionary - exprs.Add(dictVar); - - var finalLambdaExpr = Expression.Lambda>>(Expression.Block(new[] { dictVar, tempProp, propName }, exprs), new[] { instanceParam, ctxParam }); - return finalLambdaExpr.Compile(); - } - - /// - /// Generates a Conditional Expression that will retrieve the given entity value by type and set it into the current property. - /// - /// The entity type - /// The property to deserialize into - /// An Expression that represents the entity instance - /// An Expression that represents the current EntityProperty expression - /// - private static Expression GeneratePropertyReadExpressionByType(Type type, PropertyInfo property, Expression instanceParam, Expression currentEntityProperty) - { - if (property.PropertyType == typeof(string)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.String)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_StringPI.FindGetProp()))); - } - else if (property.PropertyType == typeof(byte[])) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Binary)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BinaryPI.FindGetProp()))); - } - else if (property.PropertyType == typeof(bool?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()))); - } - else if (property.PropertyType == typeof(bool)) - { - MethodInfo hasValuePI = typeof(bool?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(bool?).FindProperty("Value").FindGetProp(); - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), valuePI)))); - } - else if (property.PropertyType == typeof(DateTime?)) - { - MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); - MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp(); - - ParameterExpression tempVal = Expression.Variable(typeof(DateTime?), "tempVal"); - ConditionalExpression valToSetExpr = Expression.IfThenElse( - - // entityProperty.DateTimeOffsetValue.HasValue - Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI), - - // then //entityProperty.DateTimeOffsetValue.Value.UtcDateTime - Expression.Assign(tempVal, Expression.TypeAs(Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI), typeof(DateTime?))), - - // else - Expression.Assign(tempVal, Expression.TypeAs(Expression.Constant(null), typeof(DateTime?)))); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), - Expression.Block(new[] { tempVal }, - valToSetExpr, - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), tempVal))); - } - else if (property.PropertyType == typeof(DateTime)) - { - MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); - MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), - - // entityProperty.DateTimeOffsetValue.Value.UtcDateTime - Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI))); - } - else if (property.PropertyType == typeof(DateTimeOffset?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()))); - } - else if (property.PropertyType == typeof(DateTimeOffset)) - { - MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI)))); - } - else if (property.PropertyType == typeof(double?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()))); - } - else if (property.PropertyType == typeof(double)) - { - MethodInfo hasValuePI = typeof(double?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(double?).FindProperty("Value").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), valuePI)))); - } - else if (property.PropertyType == typeof(Guid?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()))); - } - else if (property.PropertyType == typeof(Guid)) - { - MethodInfo hasValuePI = typeof(Guid?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(Guid?).FindProperty("Value").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), valuePI)))); - } - else if (property.PropertyType == typeof(int?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()))); - } - else if (property.PropertyType == typeof(int)) - { - MethodInfo hasValuePI = typeof(int?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(int?).FindProperty("Value").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), valuePI)))); - } - else if (property.PropertyType == typeof(long?)) - { - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()))); - } - else if (property.PropertyType == typeof(long)) - { - MethodInfo hasValuePI = typeof(long?).FindProperty("HasValue").FindGetProp(); - MethodInfo valuePI = typeof(long?).FindProperty("Value").FindGetProp(); - - return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)), - Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), hasValuePI)), - Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), valuePI)))); - } - - return null; - } - - /// - /// Gets the EntityProperty from the dictionary, or returns null. Similar to IDictionary.TryGetValue with logging support. - /// - /// The key value - /// The Dictionary instance - /// The operationContext to log to. - /// - private static EntityProperty GetValueByKeyFromDictionary(string key, IDictionary dict, OperationContext operationContext) - { - EntityProperty retProp; - dict.TryGetValue(key, out retProp); - - if (retProp == null) - { - Logger.LogInformational(operationContext, SR.TraceMissingDictionaryEntry, key); - } - - return retProp; - } -#endif - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperation.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperation.Common.cs deleted file mode 100644 index 47814fc67b794..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperation.Common.cs +++ /dev/null @@ -1,265 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - - /// - /// Represents a single table operation. - /// - public sealed partial class TableOperation - { - /// - /// Creates a new instance of the class given the - /// entity to operate on and the type of operation that is being - /// performed. - /// - /// The entity on which the operation is being performed. - /// The type of operation. - internal TableOperation(ITableEntity entity, TableOperationType operationType) - { - if (entity == null && operationType != TableOperationType.Retrieve) - { - throw new ArgumentNullException("entity"); - } - - this.Entity = entity; - this.OperationType = operationType; - } - - private bool isTableEntity = false; - - internal bool IsTableEntity - { - get { return this.isTableEntity; } - set { this.isTableEntity = value; } - } - - // Retrieve operation, typically this would be in a derived class, but since we want to export to winmd, it is specialized via the below locals - internal string RetrievePartitionKey { get; set; } - - internal string RetrieveRowKey { get; set; } - - private Func, string, object> retrieveResolver = null; - - internal Func, string, object> RetrieveResolver - { - get - { - if (this.retrieveResolver == null) - { - this.retrieveResolver = DynamicEntityResolver; - } - - return this.retrieveResolver; - } - - set - { - this.retrieveResolver = value; - } - } - - /// - /// Gets the entity that is being operated upon. - /// - internal ITableEntity Entity { get; private set; } - - /// - /// Gets the type of operation. - /// - internal TableOperationType OperationType { get; private set; } - - /// - /// Creates a new table operation that deletes the given entity - /// from a table. - /// - /// The entity to be deleted from the table. - /// The object. - public static TableOperation Delete(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Delete requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForDelete); - } - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.Delete); - } - - /// - /// Creates a new table operation that inserts the given entity - /// into a table. - /// - /// The entity to be inserted into the table. - /// The object. - public static TableOperation Insert(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.Insert); - } - - /// - /// Creates a new table operation that inserts the given entity - /// into a table if the entity does not exist; if the entity does - /// exist then its contents are merged with the provided entity. - /// - /// The entity whose contents are being inserted - /// or merged. - /// The object. - public static TableOperation InsertOrMerge(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.InsertOrMerge); - } - - /// - /// Creates a new table operation that inserts the given entity - /// into a table if the entity does not exist; if the entity does - /// exist then its contents are replaced with the provided entity. - /// - /// The entity whose contents are being inserted - /// or replaced. - /// The object. - public static TableOperation InsertOrReplace(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.InsertOrReplace); - } - - /// - /// Creates a new table operation that merges the contents of - /// the given entity with the existing entity in a table. - /// - /// The entity whose contents are being merged. - /// The object. - public static TableOperation Merge(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Merge requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForMerge); - } - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.Merge); - } - - /// - /// Creates a new table operation that replaces the contents of - /// the given entity in a table. - /// - /// The entity whose contents are being replaced. - /// The object. - public static TableOperation Replace(ITableEntity entity) - { - // Validate the arguments. - CommonUtility.AssertNotNull("entity", entity); - - // Replace requires an ETag. - if (string.IsNullOrEmpty(entity.ETag)) - { - throw new ArgumentException(SR.ETagMissingForReplace); - } - - // Create and return the table operation. - return new TableOperation(entity, TableOperationType.Replace); - } - - /// - /// Creates a new table operation that replaces the contents of - /// the given entity in a table. - /// - /// The partition key of the entity to be replaced. - /// The row key of the entity to be replaced. - /// The object. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "rowkey", Justification = "Reviewed : rowkey is allowed.")] - public static TableOperation Retrieve(string partitionKey, string rowkey) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Create and return the table operation. - return new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey }; - } - - private static object DynamicEntityResolver(string partitionKey, string rowKey, DateTimeOffset timestamp, IDictionary properties, string etag) - { - ITableEntity entity = new DynamicTableEntity(); - - entity.PartitionKey = partitionKey; - entity.RowKey = rowKey; - entity.Timestamp = timestamp; - entity.ReadEntity(properties, null); - entity.ETag = etag; - - return entity; - } - - internal Uri GenerateRequestURI(Uri baseUri, string tableName) - { - if (this.OperationType == TableOperationType.Insert) - { - return NavigationHelper.AppendPathToUri(baseUri, tableName + "()"); - } - else - { - string identity = null; - if (this.isTableEntity) - { - // Note tableEntity is only used internally, so we can assume operationContext is not needed - identity = string.Format(CultureInfo.InvariantCulture, "'{0}'", this.Entity.WriteEntity(null /* OperationContext */)[TableConstants.TableName].StringValue); - } - else if (this.OperationType == TableOperationType.Retrieve) - { - // OData readers expect single quote to be escaped in a param value. - identity = string.Format(CultureInfo.InvariantCulture, "{0}='{1}',{2}='{3}'", TableConstants.PartitionKey, this.RetrievePartitionKey.Replace("'", "''"), TableConstants.RowKey, this.RetrieveRowKey.Replace("'", "''")); - } - else - { - // OData readers expect single quote to be escaped in a param value. - identity = string.Format(CultureInfo.InvariantCulture, "{0}='{1}',{2}='{3}'", TableConstants.PartitionKey, this.Entity.PartitionKey.Replace("'", "''"), TableConstants.RowKey, this.Entity.RowKey.Replace("'", "''")); - } - - return NavigationHelper.AppendPathToUri(baseUri, string.Format(CultureInfo.InvariantCulture, "{0}({1})", tableName, identity)); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperationType.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperationType.cs deleted file mode 100644 index 8911cb543513c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperationType.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Enumeration containing the types of operations that can be - /// performed by a . - /// - public enum TableOperationType - { - /// - /// Represents an insert operation. - /// - Insert, - - /// - /// Represents a delete operation. - /// - Delete, - - /// - /// Represents a replace operation. - /// - Replace, - - /// - /// Represents a merge operation. - /// - Merge, - - /// - /// Represents an insert or replace operation. - /// - InsertOrReplace, - - /// - /// Represents an insert or merge operation. - /// - InsertOrMerge, - - /// - /// Represents a retrieve operation. - /// - Retrieve - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperators.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperators.cs deleted file mode 100644 index 05fcc8fb8495c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableOperators.cs +++ /dev/null @@ -1,65 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Defines the set of Boolean operators for constructing queries. - /// - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Due to Javascript projection limitations.")] - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1303:ConstFieldNamesMustBeginWithUpperCaseLetter", Justification = "Due to Javascript projection limitations..")] - public static class TableOperators - { -#if WINDOWS_RT - internal const string and = "and"; - internal const string not = "not"; - internal const string or = "or"; - - public static string And - { - get { return and; } - } - - public static string Not - { - get { return not; } - } - - public static string Or - { - get { return or; } - } -#else - /// - /// Represents the And operator. - /// - public const string And = "and"; - - /// - /// Represents the Not operator. - /// - public const string Not = "not"; - - /// - /// Represents the Or operator. - /// - public const string Or = "or"; -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TablePermissions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TablePermissions.cs deleted file mode 100644 index b7d9f0126e834..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TablePermissions.cs +++ /dev/null @@ -1,39 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Represents the permissions for a table. - /// - public sealed class TablePermissions - { - /// - /// Initializes a new instance of the class. - /// - public TablePermissions() - { - this.SharedAccessPolicies = new SharedAccessTablePolicies(); - } - - /// - /// Gets the set of shared access policies for the container. - /// - /// The set of shared access policies for the container. - public SharedAccessTablePolicies SharedAccessPolicies { get; private set; } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuery.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuery.Common.cs deleted file mode 100644 index df35893f70f4c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuery.Common.cs +++ /dev/null @@ -1,361 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Text; - -#if WINDOWS_RT - using System.Runtime.InteropServices.WindowsRuntime; -#endif - - /// - /// Represents a query against a specified table. - /// - /// The class aggregates and encodes the query parameters to pass with the request when the query is executed. - /// To execute the query, call the executeQuery or executeQuerySegmented method of the class. - public sealed partial class TableQuery - { - #region Filter Generation - - /// - /// Generates a property filter condition string for the string value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A string containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterCondition(string propertyName, string operation, string givenValue) - { - givenValue = givenValue ?? string.Empty; - return GenerateFilterCondition(propertyName, operation, givenValue, EdmType.String); - } - - /// - /// Generates a property filter condition string for the boolean value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A bool containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForBool(string propertyName, string operation, bool givenValue) - { - return GenerateFilterCondition(propertyName, operation, givenValue ? "true" : "false", EdmType.Boolean); - } - - /// - /// Generates a property filter condition string for the binary value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A byte array containing the value to compare with the property. - /// A string containing the formatted filter condition. - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:ParameterMustNotSpanMultipleLines", Justification = "Needed for Common Code preprocessor directives.")] - public static string GenerateFilterConditionForBinary( - string propertyName, - string operation, -#if WINDOWS_RT - [ReadOnlyArray] -#endif - byte[] givenValue) - { - CommonUtility.AssertNotNull("value", givenValue); - - StringBuilder sb = new StringBuilder(); - - foreach (byte b in givenValue) - { - sb.AppendFormat("{0:x2}", b); - } - - return GenerateFilterCondition(propertyName, operation, sb.ToString(), EdmType.Binary); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForDate(string propertyName, string operation, DateTimeOffset givenValue) - { - return GenerateFilterCondition(propertyName, operation, givenValue.UtcDateTime.ToString("o", CultureInfo.InvariantCulture), EdmType.DateTime); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForDouble(string propertyName, string operation, double givenValue) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(givenValue, CultureInfo.InvariantCulture), EdmType.Double); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ForInt", Justification = "Reviewed")] - public static string GenerateFilterConditionForInt(string propertyName, string operation, int givenValue) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(givenValue, CultureInfo.InvariantCulture), EdmType.Int32); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForLong(string propertyName, string operation, long givenValue) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(givenValue, CultureInfo.InvariantCulture), EdmType.Int64); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForGuid(string propertyName, string operation, Guid givenValue) - { - CommonUtility.AssertNotNull("value", givenValue); - return GenerateFilterCondition(propertyName, operation, givenValue.ToString(), EdmType.Guid); - } - - /// - /// Generates a property filter condition string for the value, formatted as the specified . - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A string containing the value to compare with the property. - /// The to format the value as. - /// A string containing the formatted filter condition. - private static string GenerateFilterCondition(string propertyName, string operation, string givenValue, EdmType edmType) - { - string valueOperand = null; - - if (edmType == EdmType.Boolean || edmType == EdmType.Double || edmType == EdmType.Int32) - { - valueOperand = givenValue; - } - else if (edmType == EdmType.Int64) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "{0}L", givenValue); - } - else if (edmType == EdmType.DateTime) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "datetime'{0}'", givenValue); - } - else if (edmType == EdmType.Guid) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "guid'{0}'", givenValue); - } - else if (edmType == EdmType.Binary) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "X'{0}'", givenValue); - } - else - { - // OData readers expect single quote to be escaped in a param value. - valueOperand = string.Format(CultureInfo.InvariantCulture, "'{0}'", givenValue.Replace("'", "''")); - } - - return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", propertyName, operation, valueOperand); - } - - /// - /// Creates a filter condition using the specified logical operator on two filter conditions. - /// - /// A string containing the first formatted filter condition. - /// A string containing Operators.AND or Operators.OR. - /// A string containing the second formatted filter condition. - /// A string containing the combined filter expression. - [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "string", Justification = "Back compatibility.")] - public static string CombineFilters(string filterA, string operatorString, string filterB) - { - return string.Format(CultureInfo.InvariantCulture, "({0}) {1} ({2})", filterA, operatorString, filterB); - } - - #endregion - - #region Properties - - private int? takeCount = null; - - /// - /// Gets or sets the number of entities the table query will return. - /// - /// The maximum number of entities for the table query to return. - public int? TakeCount - { - get - { - return this.takeCount; - } - - set - { - if (value.HasValue && value.Value <= 0) - { - throw new ArgumentException(SR.TakeCountNotPositive); - } - - this.takeCount = value; - } - } - - /// - /// Gets or sets the filter expression to use in the table query. - /// - /// A string containing the filter expression to use in the query. - public string FilterString { get; set; } - - /// - /// Gets or sets the property names of the table entity properties to return when the table query is executed. - /// - /// A list of strings containing the property names of the table entity properties to return when the query is executed. - public IList SelectColumns { get; set; } - - /// - /// Defines the property names of the table entity properties to return when the table query is executed. - /// - /// The select clause is optional on a table query, used to limit the table properties returned from the server. By default, a query will return all properties from the table entity. - /// A list of string objects containing the property names of the table entity properties to return when the query is executed. - /// A instance set with the table entity properties to return. - public TableQuery Select(IList columns) - { - this.SelectColumns = columns; - return this; - } - - /// - /// Defines the upper bound for the number of entities the query returns. - /// - /// The maximum number of entities for the table query to return. - /// A instance set with the number of entities to return. - [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "Reviewed.")] - public TableQuery Take(int? take) - { - this.TakeCount = take; - return this; - } - - /// - /// Defines a filter expression for the table query. Only entities that satisfy the specified filter expression will be returned by the query. - /// - /// Setting a filter expression is optional; by default, all entities in the table are returned if no filter expression is specified in the table query. - /// A string containing the filter expression to apply to the table query. - /// A instance set with the filter on entities to return. - public TableQuery Where(string filter) - { - this.FilterString = filter; - return this; - } - #endregion - - #region Impl - - internal UriQueryBuilder GenerateQueryBuilder() - { - UriQueryBuilder builder = new UriQueryBuilder(); - - // filter - if (!string.IsNullOrEmpty(this.FilterString)) - { - builder.Add(TableConstants.Filter, this.FilterString); - } - - // take - if (this.takeCount.HasValue) - { - builder.Add(TableConstants.Top, Convert.ToString(Math.Min(this.takeCount.Value, TableConstants.TableServiceMaxResults), CultureInfo.InvariantCulture)); - } - - // select - if (this.SelectColumns != null && this.SelectColumns.Count > 0) - { - StringBuilder colBuilder = new StringBuilder(); - bool foundRk = false; - bool foundPk = false; - bool foundTs = false; - - for (int m = 0; m < this.SelectColumns.Count; m++) - { - if (this.SelectColumns[m] == TableConstants.PartitionKey) - { - foundPk = true; - } - else if (this.SelectColumns[m] == TableConstants.RowKey) - { - foundRk = true; - } - else if (this.SelectColumns[m] == TableConstants.Timestamp) - { - foundTs = true; - } - - colBuilder.Append(this.SelectColumns[m]); - if (m < this.SelectColumns.Count - 1) - { - colBuilder.Append(","); - } - } - - if (!foundPk) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.PartitionKey); - } - - if (!foundRk) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.RowKey); - } - - if (!foundTs) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.Timestamp); - } - - builder.Add(TableConstants.Select, colBuilder.ToString()); - } - - return builder; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryGeneric.Common.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryGeneric.Common.cs deleted file mode 100644 index 3a39eaecc3bc6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryGeneric.Common.cs +++ /dev/null @@ -1,379 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Text; - -#if WINDOWS_RT - using System.Runtime.InteropServices.WindowsRuntime; -#endif - - /// - /// Represents a query against a specified table. - /// - public sealed partial class TableQuery - { - #region Filter Generation - - /// - /// Generates a property filter condition string for the string value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A string containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterCondition(string propertyName, string operation, string value) - { - value = value ?? string.Empty; - return GenerateFilterCondition(propertyName, operation, value, EdmType.String); - } - - /// - /// Generates a property filter condition string for the boolean value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A bool containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForBool(string propertyName, string operation, bool value) - { - return GenerateFilterCondition(propertyName, operation, value ? "true" : "false", EdmType.Boolean); - } - - /// - /// Generates a property filter condition string for the binary value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A byte array containing the value to compare with the property. - /// A string containing the formatted filter condition. - [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:ParameterMustNotSpanMultipleLines", Justification = "Needed for Common Code preprocessor directives.")] - public static string GenerateFilterConditionForBinary( - string propertyName, - string operation, -#if WINDOWS_RT - [ReadOnlyArray] -#endif - byte[] value) - { - CommonUtility.AssertNotNull("value", value); - - StringBuilder sb = new StringBuilder(); - - foreach (byte b in value) - { - sb.AppendFormat("{0:x2}", b); - } - - return GenerateFilterCondition(propertyName, operation, sb.ToString(), EdmType.Binary); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForDate(string propertyName, string operation, DateTimeOffset value) - { - return GenerateFilterCondition(propertyName, operation, value.UtcDateTime.ToString("o", CultureInfo.InvariantCulture), EdmType.DateTime); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForDouble(string propertyName, string operation, double value) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(value, CultureInfo.InvariantCulture), EdmType.Double); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "ForInt", Justification = "Reviewed")] - public static string GenerateFilterConditionForInt(string propertyName, string operation, int value) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(value, CultureInfo.InvariantCulture), EdmType.Int32); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForLong(string propertyName, string operation, long value) - { - return GenerateFilterCondition(propertyName, operation, Convert.ToString(value, CultureInfo.InvariantCulture), EdmType.Int64); - } - - /// - /// Generates a property filter condition string for the value. - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A containing the value to compare with the property. - /// A string containing the formatted filter condition. - public static string GenerateFilterConditionForGuid(string propertyName, string operation, Guid value) - { - CommonUtility.AssertNotNull("value", value); - return GenerateFilterCondition(propertyName, operation, value.ToString(), EdmType.Guid); - } - - /// - /// Generates a property filter condition string for the value, formatted as the specified . - /// - /// A string containing the name of the property to compare. - /// A string containing the comparison operator to use. - /// A string containing the value to compare with the property. - /// The to format the value as. - /// A string containing the formatted filter condition. - private static string GenerateFilterCondition(string propertyName, string operation, string value, EdmType edmType) - { - string valueOperand = null; - - if (edmType == EdmType.Boolean || edmType == EdmType.Double || edmType == EdmType.Int32) - { - valueOperand = value; - } - else if (edmType == EdmType.Int64) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "{0}L", value); - } - else if (edmType == EdmType.DateTime) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "datetime'{0}'", value); - } - else if (edmType == EdmType.Guid) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "guid'{0}'", value); - } - else if (edmType == EdmType.Binary) - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "X'{0}'", value); - } - else - { - valueOperand = string.Format(CultureInfo.InvariantCulture, "'{0}'", value); - } - - return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", propertyName, operation, valueOperand); - } - - /// - /// Creates a filter condition using the specified logical operator on two filter conditions. - /// - /// A string containing the first formatted filter condition. - /// A string containing Operators.AND or Operators.OR. - /// A string containing the second formatted filter condition. - /// A string containing the combined filter expression. - [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "string", Justification = "Back compatibility.")] - public static string CombineFilters(string filterA, string operatorString, string filterB) - { - return string.Format(CultureInfo.InvariantCulture, "({0}) {1} ({2})", filterA, operatorString, filterB); - } - - #endregion - - #region Properties - - private int? takeCount = null; - - /// - /// Gets or sets the number of entities the query returns specified in the table query. - /// - /// The maximum number of entities for the table query to return. - public int? TakeCount - { - get - { - return this.takeCount; - } - - set - { - if (value.HasValue && value.Value <= 0) - { - throw new ArgumentException(SR.TakeCountNotPositive); - } - - this.takeCount = value; - } - } - - /// - /// Gets or sets the filter expression to use in the table query. - /// - /// A string containing the filter expression to use in the query. - public string FilterString { get; set; } - - /// - /// Gets or sets the property names of the table entity properties to return when the table query is executed. - /// - /// A list of strings containing the property names of the table entity properties to return when the query is executed. - public IList SelectColumns { get; set; } - - /// - /// Defines the property names of the table entity properties to return when the table query is executed. - /// - /// The select clause is optional on a table query, used to limit the table properties returned from the server. By default, a query will return all properties from the table entity. - /// A list of string objects containing the property names of the table entity properties to return when the query is executed. - /// A instance set with the table entity properties to return. - public TableQuery Select(IList columns) - { -#if WINDOWS_DESKTOP - if (this.Expression != null) - { - throw new NotSupportedException(SR.TableQueryFluentMethodNotAllowed); - } -#endif - - this.SelectColumns = columns; - return this; - } - - /// - /// Defines the upper bound for the number of entities the query returns. - /// - /// The maximum number of entities for the table query to return. - /// A instance set with the number of entities to return. - [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "Reviewed.")] - public TableQuery Take(int? take) - { -#if WINDOWS_DESKTOP - if (this.Expression != null) - { - throw new NotSupportedException(SR.TableQueryFluentMethodNotAllowed); - } -#endif - - this.TakeCount = take; - return this; - } - - /// - /// Defines a filter expression for the table query. Only entities that satisfy the specified filter expression will be returned by the query. - /// - /// Setting a filter expression is optional; by default, all entities in the table are returned if no filter expression is specified in the table query. - /// A string containing the filter expression to apply to the table query. - /// A instance set with the filter on entities to return. - public TableQuery Where(string filter) - { -#if WINDOWS_DESKTOP - if (this.Expression != null) - { - throw new NotSupportedException(SR.TableQueryFluentMethodNotAllowed); - } -#endif - - this.FilterString = filter; - return this; - } - #endregion - - #region Impl - - internal UriQueryBuilder GenerateQueryBuilder() - { - UriQueryBuilder builder = new UriQueryBuilder(); - - // filter - if (!string.IsNullOrEmpty(this.FilterString)) - { - builder.Add(TableConstants.Filter, this.FilterString); - } - - // take - if (this.takeCount.HasValue) - { - builder.Add(TableConstants.Top, Convert.ToString(Math.Min(this.takeCount.Value, TableConstants.TableServiceMaxResults), CultureInfo.InvariantCulture)); - } - - // select - if (this.SelectColumns != null && this.SelectColumns.Count > 0) - { - StringBuilder colBuilder = new StringBuilder(); - bool foundRk = false; - bool foundPk = false; - bool foundTs = false; - - for (int m = 0; m < this.SelectColumns.Count; m++) - { - if (this.SelectColumns[m] == TableConstants.PartitionKey) - { - foundPk = true; - } - else if (this.SelectColumns[m] == TableConstants.RowKey) - { - foundRk = true; - } - else if (this.SelectColumns[m] == TableConstants.Timestamp) - { - foundTs = true; - } - - colBuilder.Append(this.SelectColumns[m]); - if (m < this.SelectColumns.Count - 1) - { - colBuilder.Append(","); - } - } - - if (!foundPk) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.PartitionKey); - } - - if (!foundRk) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.RowKey); - } - - if (!foundTs) - { - colBuilder.Append(","); - colBuilder.Append(TableConstants.Timestamp); - } - - builder.Add(TableConstants.Select, colBuilder.ToString()); - } - - return builder; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryProvider.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryProvider.cs deleted file mode 100644 index 526331ede3c8f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQueryProvider.cs +++ /dev/null @@ -1,137 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Queryable; - using System; - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - - internal class TableQueryProvider : IQueryProvider - { - internal CloudTable Table { get; private set; } - - public TableQueryProvider(CloudTable table) - { - this.Table = table; - } - - public IQueryable CreateQuery(Expression expression) - { - CommonUtility.AssertNotNull("expression", expression); - return new TableQuery(expression, this); - } - - public IQueryable CreateQuery(Expression expression) - { - CommonUtility.AssertNotNull("expression", expression); - Type elementType = TypeSystem.GetElementType(expression.Type); - - Type queryType = typeof(TableQuery<>).MakeGenericType(elementType); - object[] args = new object[] { expression, this }; - - ConstructorInfo ci = queryType.GetConstructor( - BindingFlags.NonPublic | BindingFlags.Instance, - null, - new Type[] { typeof(Expression), typeof(TableQueryProvider) }, - null); - - return (IQueryable)ConstructorInvoke(ci, args); - } - - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining | System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] - public object Execute(Expression expression) - { - CommonUtility.AssertNotNull("expression", expression); - - return ReflectionUtil.TableQueryProviderReturnSingletonMethodInfo.MakeGenericMethod(expression.Type).Invoke(this, new object[] { expression }); - } - - public TResult Execute(Expression expression) - { - CommonUtility.AssertNotNull("expression", expression); - - return (TResult)ReflectionUtil.TableQueryProviderReturnSingletonMethodInfo.MakeGenericMethod(typeof(TResult)).Invoke(this, new object[] { expression }); - } - - internal TElement ReturnSingleton(Expression expression) - { - IQueryable query = new TableQuery(expression, this); - - MethodCallExpression mce = expression as MethodCallExpression; - - SequenceMethod sequenceMethod; - if (ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod)) - { - switch (sequenceMethod) - { - case SequenceMethod.Single: - return query.AsEnumerable().Single(); - case SequenceMethod.SingleOrDefault: - return query.AsEnumerable().SingleOrDefault(); - case SequenceMethod.First: - return query.AsEnumerable().First(); - case SequenceMethod.FirstOrDefault: - return query.AsEnumerable().FirstOrDefault(); -/* -if !ASTORIA_LIGHT - case SequenceMethod.LongCount: - case SequenceMethod.Count: - return (TElement)Convert.ChangeType(((TableQuery)query).GetQuerySetCount(this.Context), typeof(TElement), System.Globalization.CultureInfo.InvariantCulture.NumberFormat); -#endif -*/ - } - } - - throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, SR.ALinqMethodNotSupported, mce.Method.Name)); - } - - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining | System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] - internal static object ConstructorInvoke(ConstructorInfo constructor, object[] arguments) - { - if (constructor == null) - { - throw new MissingMethodException(); - } - -#if ASTORIA_LIGHT && !ASTORIA_LIGHT_WP - int argumentCount = (arguments == null) ? 0 : arguments.Length; - ParameterExpression argumentsExpression = Expression.Parameter(typeof(object[]), "arguments"); - Expression[] argumentExpressions = new Expression[argumentCount]; - ParameterInfo[] parameters = constructor.GetParameters(); - for (int i = 0; i < argumentExpressions.Length; i++) - { - argumentExpressions[i] = Expression.Constant(arguments[i], parameters[i].ParameterType); - } - - Expression newExpression = Expression.New(constructor, argumentExpressions); - Expression> lambda = Expression.Lambda>( - Expression.Convert(newExpression, typeof(object)), - argumentsExpression); - object result = lambda.Compile()(arguments); - return result; -#else - return constructor.Invoke(arguments); -#endif - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuerySegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuerySegment.cs deleted file mode 100644 index ee459cabbaf04..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableQuerySegment.cs +++ /dev/null @@ -1,93 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a segment of results and contains continuation token information. - /// - /// The type of the result that the segment contains. - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Back compatibility.")] - public class TableQuerySegment : IEnumerable - { - /// - /// Stores the continuation token used to retrieve the next segment of results. - /// - private TableContinuationToken continuationToken; - - /// - /// Initializes a new instance of the class. - /// - /// The result. - internal TableQuerySegment(List result) - { - this.Results = result; - } - - internal TableQuerySegment(ResultSegment resSeg) - : this(resSeg.Results) - { - this.continuationToken = (TableContinuationToken)resSeg.ContinuationToken; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - [SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Justification = "Reviewed.")] - public List Results { get; internal set; } - - /// - /// Gets a continuation token to use to retrieve the next set of results with a subsequent call to the operation. - /// - /// The continuation token. - public TableContinuationToken ContinuationToken - { - get - { - if (this.continuationToken != null) - { - return this.continuationToken; - } - - return null; - } - - internal set - { - this.continuationToken = value; - } - } - - /// - /// Returns an enumerator that iterates through the . - /// - /// An enumerator that iterates through the . - public IEnumerator GetEnumerator() - { - return this.Results.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.Results.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableRequestOptions.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableRequestOptions.cs deleted file mode 100644 index fcacc772a9500..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableRequestOptions.cs +++ /dev/null @@ -1,88 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using System; - - /// - /// Represents a set of timeout and retry policy options that may be specified for a request against the Table service. - /// - public sealed class TableRequestOptions : IRequestOptions - { - /// - /// Initializes a new instance of the class. - /// - public TableRequestOptions() - { - } - - /// - /// Initializes a new instance of the class with the specified . - /// - /// The request options used to initialize this instance of the class. - public TableRequestOptions(TableRequestOptions other) - { - if (other != null) - { - this.ServerTimeout = other.ServerTimeout; - this.RetryPolicy = other.RetryPolicy; - this.MaximumExecutionTime = other.MaximumExecutionTime; - this.OperationExpiryTime = other.OperationExpiryTime; - } - } - - internal static TableRequestOptions ApplyDefaults(TableRequestOptions requestOptions, CloudTableClient serviceClient) - { - TableRequestOptions modifiedOptions = new TableRequestOptions(requestOptions); - modifiedOptions.RetryPolicy = modifiedOptions.RetryPolicy ?? serviceClient.RetryPolicy; - modifiedOptions.ServerTimeout = modifiedOptions.ServerTimeout ?? serviceClient.ServerTimeout; - modifiedOptions.MaximumExecutionTime = modifiedOptions.MaximumExecutionTime ?? serviceClient.MaximumExecutionTime; - - if (!modifiedOptions.OperationExpiryTime.HasValue && modifiedOptions.MaximumExecutionTime.HasValue) - { - modifiedOptions.OperationExpiryTime = DateTime.Now + modifiedOptions.MaximumExecutionTime.Value; - } - - return modifiedOptions; - } - - /// - /// Gets or sets the absolute expiry time across all potential retries for the request. - /// - internal DateTime? OperationExpiryTime { get; set; } - - /// - /// Gets or sets the retry policy for the request. - /// - /// The retry policy delegate. - public IRetryPolicy RetryPolicy { get; set; } - - /// - /// Gets or sets the server timeout for the request. - /// - /// The client and server timeout interval for the request. - public TimeSpan? ServerTimeout { get; set; } - - /// - /// Gets or sets the maximum execution time for all potential retries for the request. - /// - /// A representing the maximum execution time for retries for the request. - public TimeSpan? MaximumExecutionTime { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResult.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResult.cs deleted file mode 100644 index e5b6636d286b9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResult.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents the result of a table operation. - /// - /// The class encapsulates the HTTP response and any table entity results returned by the Storage Service REST API operation called for a particular . - public sealed class TableResult - { - /// - /// Gets or sets the result returned by the as an . - /// - /// The result of the table operation as an . - public object Result { get; set; } - - /// - /// Gets or sets the HTTP status code returned by a request. - /// - /// The HTTP status code returned by a request. - public int HttpStatusCode { get; set; } - - /// - /// Gets or sets the ETag returned with the request results. - /// - /// The ETag returned with the request results. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Etag", Justification = "Reviewed: Etag can be used for identifier names.")] - public string Etag { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResultSegment.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResultSegment.cs deleted file mode 100644 index a37d6006de3e8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableResultSegment.cs +++ /dev/null @@ -1,85 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents a segment of results, with continuation information for pagination scenarios. - /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Back compatibility.")] - public sealed class TableResultSegment : IEnumerable - { - /// - /// Initializes a new instance of the class. - /// - /// The result. - internal TableResultSegment(List result) - { - this.Results = result; - } - - /// - /// Stores the continuation token used to retrieve the next segment of results or null if there are no more results. - /// - private TableContinuationToken continuationToken; - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - public IList Results { get; internal set; } - - /// - /// Gets the continuation token used to retrieve the next segment of results. Returns null if there are no more results. - /// - /// The continuation token. - public TableContinuationToken ContinuationToken - { - get - { - if (this.continuationToken != null) - { - return this.continuationToken; - } - - return null; - } - - internal set - { - this.continuationToken = value; - } - } - - /// - /// Returns an enumerator that iterates through the segment of results. - /// - /// An enumerator that iterates through the segment of results. - public IEnumerator GetEnumerator() - { - return this.Results.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.Results.GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableServiceTable.cs b/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableServiceTable.cs deleted file mode 100644 index d01ecdd6ac577..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/Common/Table/TableServiceTable.cs +++ /dev/null @@ -1,111 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ -#if WINDOWS_DESKTOP && ! WINDOWS_PHONE - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Data.Services.Common; - - /// - /// Internal table service entity for creating tables. - /// - [DataServiceKey("TableName")] - internal class TableServiceTable - { - /// - /// Stores the table name. - /// - private string tableName; - - /// - /// Initializes a new instance of the class. - /// - public TableServiceTable() - { - } - - /// - /// Initializes a new instance of the class with the specified name. - /// - /// The name of the table. - public TableServiceTable(string name) - { - CommonUtility.CheckStringParameter(name, false, "name", TableConstants.TableServiceMaxStringPropertySizeInChars); - this.TableName = name; - } - - /// - /// Gets or sets the table name. - /// - /// The name of the table. - public string TableName - { - get - { - return this.tableName; - } - - set - { - CommonUtility.CheckStringParameter(value, false, "TableName", TableConstants.TableServiceMaxStringPropertySizeInChars); - this.tableName = value; - } - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// Returns true if the specified is equal to this instance; otherwise, false. - /// - /// - /// The parameter is null. - /// - public override bool Equals(object obj) - { - if (obj == null) - { - return false; - } - - TableServiceTable rhs = obj as TableServiceTable; - - if (rhs == null) - { - return false; - } - - return this.TableName.Equals(rhs.TableName, StringComparison.OrdinalIgnoreCase); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return this.TableName.GetHashCode(); - } - } -#endif -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/CodeAnalysisDotNet40.ruleset b/microsoft-azure-api/Services/Storage/Lib/DotNet40/CodeAnalysisDotNet40.ruleset deleted file mode 100644 index 9d90fec2a8bdb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/CodeAnalysisDotNet40.ruleset +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.csproj b/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.csproj deleted file mode 100644 index ff738c9ada3d6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.csproj +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Debug - AnyCPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3} - Library - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.Storage - v4.0 - 512 - Client - - - true - full - false - bin\Debug\ - TRACE;DEBUG;WINDOWS_DESKTOP;SYNC;APM;TASK;CODE_ANALYSIS - prompt - 4 - bin\Debug\Microsoft.WindowsAzure.Storage.xml - true - CodeAnalysisDotNet40.ruleset - - - true - MSSharedLibKey.snk - true - pdbonly - true - bin\Release\ - TRACE;WINDOWS_DESKTOP;SYNC;APM;TASK;SIGN - prompt - 4 - bin\Release\Microsoft.WindowsAzure.Storage.xml - false - CodeAnalysisDotNet40.ruleset - - - - False - ..\DotNetCommon\Dependencies\Microsoft.Data.Edm.dll - - - False - ..\DotNetCommon\Dependencies\Microsoft.Data.OData.dll - - - - - - False - ..\DotNetCommon\Dependencies\System.Spatial.dll - - - - - - - - - - Auth\Auth - - - Auth\Protocol\Protocol - - - Blob\Blob - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Queue\Protocol\Protocol - - - Table\Tables - - - Table\DataServices\DataServices - - - Table\Protocol\Protocol - - - Shared\Protocol\Protocol - - - Core\Core - - - Core\Auth\Auth - - - Core\Util\Util - - - Core\Executor\Executor - - - - - - - - - - - - - - Auth\Auth - - - - Core\Core - - - Core\Auth\Auth - - - Core\Executor\Executor - - - Core\Util\Util - - - - RetryPolicies\RetryPolicies - - - Blob\Blob - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Queue\Protocol\Protocol - - - Table\Queryable\Queryable - - - Table\Table - - - Table\Protocol\Protocol - - - Shared\Shared - - - Shared\Protocol\Protocol - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.sln b/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.sln deleted file mode 100644 index 2b7df779021b4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/DotNet40.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet40", "DotNet40.csproj", "{C6787633-B26A-4913-A762-4C0FFCEB6FE3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/GlobalSuppressions.cs b/microsoft-azure-api/Services/Storage/Lib/DotNet40/GlobalSuppressions.cs deleted file mode 100644 index db893fb621e26..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/GlobalSuppressions.cs +++ /dev/null @@ -1,413 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -// CA1000 -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterCondition(System.String,System.String,System.String)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForBinary(System.String,System.String,System.Byte[])", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForDate(System.String,System.String,System.DateTimeOffset)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForBool(System.String,System.String,System.Boolean)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#CombineFilters(System.String,System.String,System.String)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForLong(System.String,System.String,System.Int64)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForGuid(System.String,System.String,System.Guid)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForInt(System.String,System.String,System.Int32)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#GenerateFilterConditionForDouble(System.String,System.String,System.Double)", Justification = "Backward compatibility")] - -// CA1011 -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#StartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginStartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#StartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginStartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginStartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueHttpResponseParsers.#GetNextVisibleTime(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueHttpResponseParsers.#GetApproximateMessageCount(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueHttpResponseParsers.#GetPopReceipt(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetRemainingLeaseTime(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetSnapshotTime(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetCopyAttributes(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.ContainerHttpResponseParsers.#GetAcl(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginStartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetLeaseStatus(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetLeaseDuration(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetLeaseState(System.Net.HttpWebResponse)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.BlobHttpResponseParsers.#GetLeaseId(System.Net.HttpWebResponse)", Justification = "Reviewed.")] - -// CA1014 -[assembly: SuppressMessage("Microsoft.Design", "CA1014:MarkAssembliesWithClsCompliant", Justification = "Reviewed")] - -// CA1020 -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Table.DataServices", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Auth", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Auth.Protocol", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Core", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.RetryPolicies", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable", Justification = "Reviewed")] - -// CA1024 -[assembly: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.IBufferManager.#GetDefaultBufferSize()", Justification = "Reviewed")] - -// CA1026 -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#CreateAsync(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.DataServices.TableServiceContext.#SaveChangesWithRetries(System.Data.Services.Client.SaveChangesOptions,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.DataServices.TableServiceQuery`1.#Execute(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.DataServices.TableServiceQuery`1.#ExecuteSegmented(Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTableClient.#SetServiceProperties(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTableClient.#ListTablesSegmented(System.String,System.Nullable`1,Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTableClient.#ListTables(System.String,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTableClient.#GetServiceProperties(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#Create(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuerySegmented`2(Microsoft.WindowsAzure.Storage.Table.TableQuery`1,Microsoft.WindowsAzure.Storage.Table.EntityResolver`1,Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuerySegmented`1(Microsoft.WindowsAzure.Storage.Table.TableQuery,Microsoft.WindowsAzure.Storage.Table.EntityResolver`1,Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuery(Microsoft.WindowsAzure.Storage.Table.TableQuery,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#Delete(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#Execute(Microsoft.WindowsAzure.Storage.Table.TableOperation,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteBatch(Microsoft.WindowsAzure.Storage.Table.TableBatchOperation,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#GetPermissions(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuery`1(Microsoft.WindowsAzure.Storage.Table.TableQuery`1,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#SetPermissions(Microsoft.WindowsAzure.Storage.Table.TablePermissions,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#CreateIfNotExists(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#Exists(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuerySegmented(Microsoft.WindowsAzure.Storage.Table.TableQuery,Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuery`1(Microsoft.WindowsAzure.Storage.Table.TableQuery,Microsoft.WindowsAzure.Storage.Table.EntityResolver`1,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuerySegmented`1(Microsoft.WindowsAzure.Storage.Table.TableQuery`1,Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#ExecuteQuery`2(Microsoft.WindowsAzure.Storage.Table.TableQuery`1,Microsoft.WindowsAzure.Storage.Table.EntityResolver`1,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#DeleteIfExists(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#FetchAttributes(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#SetMetadata(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#ReleaseLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#CreateSnapshot(System.Collections.Generic.IDictionary`2,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadBlockList(Microsoft.WindowsAzure.Storage.Blob.BlockListingFilter,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadRangeToStream(System.IO.Stream,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#OpenRead(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#ChangeLease(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#Delete(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#StartCopyFromBlob(System.Uri,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#AcquireLease(System.Nullable`1,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadToStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadFromStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadFromStream(System.IO.Stream,System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#PutBlock(System.String,System.IO.Stream,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#AbortCopy(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#Exists(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#RenewLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BreakLease(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#StartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#PutBlockList(System.Collections.Generic.IEnumerable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DeleteIfExists(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#OpenWrite(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#SetProperties(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#AcquireLease(System.Nullable`1,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#UploadFromStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#UploadFromStream(System.IO.Stream,System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#ChangeLease(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#GetPageRanges(System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#Resize(System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#StartCopyFromBlob(System.Uri,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#Exists(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#FetchAttributes(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#StartCopyFromBlob(Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#WritePages(System.IO.Stream,System.Int64,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#ClearPages(System.Int64,System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#OpenRead(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadRangeToStream(System.IO.Stream,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#Delete(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DeleteIfExists(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadToStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#CreateSnapshot(System.Collections.Generic.IDictionary`2,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#SetMetadata(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#Create(System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#AbortCopy(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#RenewLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#OpenWrite(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#SetProperties(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BreakLease(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#ReleaseLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobDirectory.#ListBlobs(System.Boolean,Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#ListContainers(System.String,Microsoft.WindowsAzure.Storage.Blob.ContainerListingDetails,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#GetServiceProperties(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#ListContainersSegmented(System.String,Microsoft.WindowsAzure.Storage.Blob.ContainerListingDetails,System.Nullable`1,Microsoft.WindowsAzure.Storage.Blob.BlobContinuationToken,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#GetBlobReferenceFromServer(System.Uri,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#ListBlobs(System.String,System.Boolean,Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#SetServiceProperties(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#StartCopyFromBlob(System.Uri,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#FetchAttributes(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#SetMetadata(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#ReleaseLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#ChangeLease(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadRangeToStream(System.IO.Stream,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadToStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#UploadFromStream(System.IO.Stream,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#UploadFromStream(System.IO.Stream,System.Int64,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#AbortCopy(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#RenewLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#BreakLease(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#SetProperties(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DeleteIfExists(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#AcquireLease(System.Nullable`1,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#Delete(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#Exists(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#FetchAttributes(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#SetMetadata(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#ReleaseLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#Create(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#Exists(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#ChangeLease(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#CreateIfNotExists(Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#GetPermissions(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#ListBlobs(System.String,System.Boolean,Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#Delete(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#DeleteIfExists(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#GetBlobReferenceFromServer(System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#BreakLease(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#SetPermissions(Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#RenewLease(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#AcquireLease(System.Nullable`1,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#DeleteMessage(Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#GetMessages(System.Int32,System.Nullable`1,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#PeekMessages(System.Int32,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#AddMessage(Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#GetPermissions(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#GetMessage(System.Nullable`1,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#UpdateMessage(Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage,System.TimeSpan,Microsoft.WindowsAzure.Storage.Queue.MessageUpdateFields,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#Clear(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#DeleteIfExists(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#FetchAttributes(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#DeleteMessage(System.String,System.String,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#SetPermissions(Microsoft.WindowsAzure.Storage.Queue.Protocol.QueuePermissions,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#Delete(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#Create(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#SetMetadata(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#Exists(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#PeekMessage(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#CreateIfNotExists(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueueClient.#ListQueues(System.String,Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueListingDetails,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueueClient.#GetServiceProperties(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueueClient.#ListQueuesSegmented(System.String,Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueListingDetails,System.Nullable`1,Microsoft.WindowsAzure.Storage.Queue.Protocol.QueueContinuationToken,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueueClient.#SetServiceProperties(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadRangeToByteArray(System.Byte[],System.Nullable`1,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadToByteArray(System.Byte[],System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadRangeToByteArray(System.Byte[],System.Nullable`1,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadToByteArray(System.Byte[],System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadRangeToByteArray(System.Byte[],System.Nullable`1,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadToByteArray(System.Byte[],System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#OpenRead(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#CreateIfNotExists(Microsoft.WindowsAzure.Storage.Blob.BlobContainerPublicAccessType,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#Create(Microsoft.WindowsAzure.Storage.Blob.BlobContainerPublicAccessType,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadFromFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadToFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadRangeToByteArray(System.Byte[],System.Int32,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadFromByteArray(System.Byte[],System.Int32,System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadToByteArray(System.Byte[],System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadText(System.String,System.Text.Encoding,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadText(System.Text.Encoding,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#UploadFromFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadToFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#UploadFromByteArray(System.Byte[],System.Int32,System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadToByteArray(System.Byte[],System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadRangeToByteArray(System.Byte[],System.Int32,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadToByteArray(System.Byte[],System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadToFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#UploadFromFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#UploadFromByteArray(System.Byte[],System.Int32,System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.ICloudBlob.#DownloadRangeToByteArray(System.Byte[],System.Int32,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#ExecuteSegmented(Microsoft.WindowsAzure.Storage.Table.TableContinuationToken,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#Execute(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] -[assembly: SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#SetSequenceNumber(Microsoft.WindowsAzure.Storage.Blob.SequenceNumberAction,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Backward compatibility")] - -// CA1031 -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginOpenWrite(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.Executor.#ExecuteSync`1(Microsoft.WindowsAzure.Storage.Core.Executor.StorageCommandBase`1,Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.Executor.#EndResponseStreamCopy`1(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadToFileCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#UploadFromFileCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadTextCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#DownloadRangeToByteArrayCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#UploadFromFileCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadRangeToByteArrayCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#DownloadToFileCallback(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions+<>c__DisplayClass4.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.#CreateCallback`1(System.Threading.Tasks.TaskCompletionSource`1,System.Nullable`1,System.Func`2)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.#CreateCallbackVoid(System.Threading.Tasks.TaskCompletionSource`1,System.Nullable`1,System.Action`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions+<>c__DisplayClass1`1.#b__0(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable+<>c__DisplayClassc.#b__a(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable+<>c__DisplayClass5.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.TableExecutor+<>c__DisplayClass5`2.#b__2(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass27.#b__24(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass1.#b__0(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass5.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer+<>c__DisplayClass6.#b__4(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer+<>c__DisplayClass6.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass20.#b__1d(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream+<>c__DisplayClass7.#b__6(System.Boolean)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass25.#b__23(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass21.#b__1e(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass21.#b__1f(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream+<>c__DisplayClassa.#b__9(System.Boolean)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass10.#b__a(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass1.#b__0(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass7.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass7.#b__4(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClassf+<>c__DisplayClass11.#b__e(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClassf.#b__d(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClasse+<>c__DisplayClass12.#b__c(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient+<>c__DisplayClass4.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer+<>c__DisplayClassf.#b__d(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer+<>c__DisplayClassf.#b__c(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass15.#b__14(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass1a.#b__18(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob+<>c__DisplayClass1a.#b__17(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClasse.#b__b(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob+<>c__DisplayClass2c.#b__2a(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue+<>c__DisplayClass5.#b__3(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue+<>c__DisplayClassc.#b__a(System.IAsyncResult)", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.CloudStorageAccount.#TryParse(System.String,Microsoft.WindowsAzure.Storage.CloudStorageAccount&)", Justification = "Reviewed")] - -// CA1040 -[assembly: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.IContinuationToken", Justification = "Reviewed : Specifies a common base type a continuation token can be cast to")] -[assembly: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.IListBlobEntry", Justification = "Reviewed : Specifies a common base type a ListBlobEntry can be cast to")] - -// CA1051 -[assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Shared.Protocol.ResponseParsingBase`1.#reader", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Shared.Protocol.ResponseParsingBase`1.#allObjectsParsed", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Shared.Protocol.ResponseParsingBase`1.#outstandingObjectsToParse", Justification = "Reviewed.")] - -// CA1062 -[assembly: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.DataServices.TableServiceContext.#.ctor(Microsoft.WindowsAzure.Storage.Table.CloudTableClient)", Justification = "Reviewed")] - -// CA1307 -[assembly: SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Protocol.TableRequest.#ExtractEntityIndexFromExtendedErrorInformation(Microsoft.WindowsAzure.Storage.RequestResult)", MessageId = "System.String.IndexOf(System.String)", Justification = "Compatibility with RT")] - -// CA1308 -[assembly: SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.ContainerHttpWebRequestFactory.#Create(System.Uri,System.Nullable`1,Microsoft.WindowsAzure.Storage.OperationContext,Microsoft.WindowsAzure.Storage.Blob.BlobContainerPublicAccessType)", Justification = "Reviewed")] - -// CA1502 -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.Executor.#ExecuteSync`1(Microsoft.WindowsAzure.Storage.Core.Executor.StorageCommandBase`1,Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ClientConvert.#ChangeType(System.String,System.Type)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ClientConvert.#ToString(System.Object,System.Boolean)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ExpressionNormalizer.#VisitMethodCallNoRewrite(System.Linq.Expressions.MethodCallExpression)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ResourceBinder.#VisitMethodCall(System.Linq.Expressions.MethodCallExpression)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.Protocol.ListBlobsResponse+d__0.#MoveNext()", Justification = "Reviewed")] - -// CA1505 -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ReflectionUtil.#.cctor()", Justification = "Reviewed")] - -// CA1506 -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginUploadFromStreamHelper(System.IO.Stream,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#ListBlobsImpl(System.String,System.Nullable`1,System.Boolean,Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.Blob.BlobContinuationToken)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue", Justification = "Reviewed")] - -// CA1710 -[assembly: SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1", Justification = "Reviewed")] - -// CA1716 -[assembly: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "namespace", Target = "Microsoft.WindowsAzure.Storage.Shared.Protocol", MessageId = "Shared", Justification = "Back compatibility.")] - -// CA1801 -[assembly: SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "columns", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery.#Project`1(!!0,System.String[])", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "options", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ExpressionParser.#VisitCustomQueryOptions(System.Collections.Generic.Dictionary`2)", Justification = "Reviewed")] - -// CA1810 -[assembly: SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Logger.#.cctor()", Justification = "Reviewed - Used to initilialize static data before any static members are referenced")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableEntity.#.cctor()", Justification = "Reviewed - Used to initilialize static data before any static members are referenced")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Shared.Protocol.Constants+HeaderConstants.#.cctor()", Justification = "Execution Order matters.")] - -// CA1822 -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ExpressionParser.#VisitCustomQueryOptions(System.Collections.Generic.Dictionary`2)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ExpressionWriter.#TypeNameForUri(System.Type)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.MultiBufferMemoryStream.#EndFastCopyTo(System.IAsyncResult)", Justification = "APM end methods should not be static")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#EndExecuteQuerySegmented(System.IAsyncResult)", Justification = "APM end methods should not be static")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#EndExecuteQuerySegmented`1(System.IAsyncResult)", Justification = "APM end methods should not be static")] -[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery.#EndExecuteQuerySegmented(System.IAsyncResult)", Justification = "APM end methods should not be static")] - -// CA1823 -[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Queryable.ResourceBinder+PropertyInfoEqualityComparer.#Instance", Justification = "Reviewed")] - -// CA2000 -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.#WriteToAsync`1(System.IO.Stream,System.IO.Stream,System.Nullable`1,System.Boolean,Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1,Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor,System.Action`1>)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.#WriteToSync`1(System.IO.Stream,System.IO.Stream,System.Nullable`1,System.Boolean,System.Boolean,Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1,Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.StorageCommandAsyncResult.#LazyCreateWaitHandle()", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTableClient.#SetServicePropertiesImpl(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#SetAclImpl(Microsoft.WindowsAzure.Storage.Table.TablePermissions,Microsoft.WindowsAzure.Storage.Table.TableRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#BeginCreateIfNotExists(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.CloudTable.#BeginDeleteIfExists(Microsoft.WindowsAzure.Storage.Table.TableRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.TableExecutor.#BeginExecuteAsync`2(Microsoft.WindowsAzure.Storage.Core.Executor.TableCommand`2,Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.TableExecutor.#ExecuteSync`2(Microsoft.WindowsAzure.Storage.Core.Executor.TableCommand`2,Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.Executor.#BeginExecuteAsync`1(Microsoft.WindowsAzure.Storage.Core.Executor.RESTCommand`1,Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.RequestResult.#TranslateFromExceptionMessage(System.String)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#PutBlock(System.String,System.IO.Stream,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginPutBlock(System.String,System.IO.Stream,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginOpenRead(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#PutBlockListImpl(System.Collections.Generic.IEnumerable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginOpenWrite(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDeleteIfExists(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.#BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginDeleteIfExists(Microsoft.WindowsAzure.Storage.Blob.DeleteSnapshotsOption,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#WritePages(System.IO.Stream,System.Int64,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginWritePages(System.IO.Stream,System.Int64,System.String,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginOpenWrite(System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginOpenRead(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient.#SetServicePropertiesImpl(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStreamBase.#.ctor(Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobReadStream.#BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#SetPermissionsImpl(Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#BeginDeleteIfExists(Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpWebRequestFactory.#BuildRequestForTableOperation(System.Uri,Microsoft.WindowsAzure.Storage.Core.UriQueryBuilder,System.Nullable`1,Microsoft.WindowsAzure.Storage.Table.TableOperation,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpWebRequestFactory.#BuildRequestForTableBatchOperation(System.Uri,Microsoft.WindowsAzure.Storage.Core.UriQueryBuilder,System.Nullable`1,System.Uri,System.String,Microsoft.WindowsAzure.Storage.Table.TableBatchOperation,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#SetPermissionsImpl(Microsoft.WindowsAzure.Storage.Queue.Protocol.QueuePermissions,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#AddMessageImpl(Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#BeginDeleteIfExists(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#BeginCreateIfNotExists(Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueue.#UpdateMessageImpl(Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage,System.TimeSpan,Microsoft.WindowsAzure.Storage.Queue.MessageUpdateFields,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Queue.CloudQueueClient.#SetServicePropertiesImpl(Microsoft.WindowsAzure.Storage.Shared.Protocol.ServiceProperties,Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.#BeginCommit(System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.MultiBufferMemoryStream.#BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.MultiBufferMemoryStream.#BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.MultiBufferMemoryStream.#BeginFastCopyTo(System.IO.Stream,System.Nullable`1,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDownloadToByteArray(System.Byte[],System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDownloadRangeToByteArray(System.Byte[],System.Nullable`1,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginDownloadToByteArray(System.Byte[],System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginDownloadRangeToByteArray(System.Byte[],System.Nullable`1,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.#BeginCreateIfNotExists(Microsoft.WindowsAzure.Storage.Blob.BlobContainerPublicAccessType,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.SyncMemoryStream.#BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.SyncMemoryStream.#BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)", Justification = "Reviewed.")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.#WriteToAsync`1(System.IO.Stream,System.IO.Stream,System.Nullable`1,System.Nullable`1,System.Boolean,Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1,Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor,System.Action`1>)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.#WriteToSync`1(System.IO.Stream,System.IO.Stream,System.Nullable`1,System.Nullable`1,System.Boolean,System.Boolean,Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1,Microsoft.WindowsAzure.Storage.Core.Util.StreamDescriptor)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDownloadToFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginUploadFromFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDownloadText(System.Text.Encoding,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginDownloadRangeToByteArray(System.Byte[],System.Int32,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.#BeginUploadFromByteArray(System.Byte[],System.Int32,System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginDownloadToFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginUploadFromFile(System.String,System.IO.FileMode,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginDownloadRangeToByteArray(System.Byte[],System.Int32,System.Nullable`1,System.Nullable`1,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob.#BeginUploadFromByteArray(System.Byte[],System.Int32,System.Int32,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext,System.AsyncCallback,System.Object)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Blob.BlobWriteStreamBase.#.ctor(Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient,Microsoft.WindowsAzure.Storage.Blob.BlobType,Microsoft.WindowsAzure.Storage.AccessCondition,Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.APMWithTimeout.#RunWithTimeout(System.Func`3,System.AsyncCallback,System.Threading.TimerCallback,System.Object,System.TimeSpan)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.Executor.#EndOperation`1(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.MD5Wrapper.#.ctor()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Executor.TableExecutor.#EndOperation`2(Microsoft.WindowsAzure.Storage.Core.Executor.ExecutionState`1)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpWebRequestFactory.#BuildRequestForTableOperation(System.Uri,Microsoft.WindowsAzure.Storage.Core.UriQueryBuilder,Microsoft.WindowsAzure.Storage.IBufferManager,System.Nullable`1,Microsoft.WindowsAzure.Storage.Table.TableOperation,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpWebRequestFactory.#BuildRequestForTableBatchOperation(System.Uri,Microsoft.WindowsAzure.Storage.Core.UriQueryBuilder,Microsoft.WindowsAzure.Storage.IBufferManager,System.Nullable`1,System.Uri,System.String,Microsoft.WindowsAzure.Storage.Table.TableBatchOperation,Microsoft.WindowsAzure.Storage.OperationContext)", Justification = "Reviewed")] - -// CA2208 -[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.AsyncStreamCopier`1.#EndOperation(System.IAsyncResult)", Justification = "Reviewed")] - -// CA2227 -[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery`1.#SelectColumns", Justification = "Back compatibility")] -[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.TableQuery.#SelectColumns", Justification = "Back compatibility")] -[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Table.DynamicTableEntity.#Properties", Justification = "Back compatibility")] -[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.OperationContext.#UserHeaders", Justification = "Back compatibility")] - -// CA5350 -[assembly: SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#.ctor()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#HashFinal()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#HashCore(System.Byte[],System.Int32,System.Int32)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Cryptographic.Standard", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#Initialize()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Security.Cryptography", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#HashFinal()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Security.Cryptography", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#HashCore(System.Byte[],System.Int32,System.Int32)", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Security.Cryptography", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.MD5Wrapper.#.ctor()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Security.Cryptography", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#.ctor()", Justification = "Reviewed")] -[assembly: SuppressMessage("Microsoft.Security.Cryptography", "CA5350:MD5CannotBeUsed", Scope = "member", Target = "Microsoft.WindowsAzure.Storage.Core.Util.NativeMD5.#Initialize()", Justification = "Reviewed")] \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Lib/DotNet40/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/DotNet40/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Lib/DotNet40/Properties/AssemblyInfo.cs deleted file mode 100644 index a4bc413e734f0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.Storage.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a89a167c-9cc6-46b5-a50b-697b69bfe078")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] - -#if SIGN -[assembly: InternalsVisibleTo( - "Microsoft.WindowsAzure.Storage.Test, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67" + - "871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0b" + - "d333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307" + - "e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c3" + - "08055da9")] -#else -[assembly: InternalsVisibleTo("Microsoft.WindowsAzure.Storage.Test")] -#endif -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/Settings.StyleCop b/microsoft-azure-api/Services/Storage/Lib/DotNet40/Settings.StyleCop deleted file mode 100644 index a05bc900d4e36..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/Settings.StyleCop +++ /dev/null @@ -1,322 +0,0 @@ - - - - abc - Acl - api - Auth - Bool - canonicalizing - creds - dequeue - dequeued - dest - Edm - EdmType - Enum - Eq - etag - ETag - Fisma - func - impl - Md - myblob - mycontainer - myfolder - parsable - Postcondition - Retryable - sas - testaccount - testcontainer - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNet40/WindowsAzure.Storage.nuspec b/microsoft-azure-api/Services/Storage/Lib/DotNet40/WindowsAzure.Storage.nuspec deleted file mode 100644 index 024b8a644464c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNet40/WindowsAzure.Storage.nuspec +++ /dev/null @@ -1,32 +0,0 @@ - - - - WindowsAzure.Storage - 2.1.0.4 - Windows Azure Storage - Microsoft - Microsoft - http://go.microsoft.com/fwlink/?LinkId=235170 - http://go.microsoft.com/fwlink/?LinkId=235168 - http://go.microsoft.com/fwlink/?LinkID=288890 - true - This client library enables working with the Windows Azure storage services which include the blob service for storing binary and text data, the table service for storing structured non-relational data, and the queue service for storing messages that may be accessed by a client. -For this release see notes - http://msdn.microsoft.com/en-us/library/windowsazure/jj721952.aspx -Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ - A client library for working with Windows Azure storage services including blobs, tables, and queues. - Microsoft, Azure, Storage, Table, Blob, Queue, Scalable, windowsazureofficial - - - - - - - - - - - - - - - diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/IAuthenticationHandler.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/IAuthenticationHandler.cs deleted file mode 100644 index a10c764bd3fe9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/IAuthenticationHandler.cs +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using System.Net; - - /// - /// Represents a handler that signs HTTP requests. - /// - public interface IAuthenticationHandler - { - /// - /// Signs the specified HTTP request so it can be authenticated by the Windows Azure storage services. - /// - /// The HTTP request to sign. - /// An object for tracking the current operation. - void SignRequest(HttpWebRequest request, OperationContext operationContext); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/NoOpAuthenticationHandler.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/NoOpAuthenticationHandler.cs deleted file mode 100644 index 65c595c32aca4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/NoOpAuthenticationHandler.cs +++ /dev/null @@ -1,44 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using System.Net; - - /// - /// Represents a handler that signs HTTP requests with no authentication information. - /// - public sealed class NoOpAuthenticationHandler : IAuthenticationHandler - { - /// - /// Initializes a new instance of the class. - /// - public NoOpAuthenticationHandler() - { - } - - /// - /// Signs the specified HTTP request with no authentication information. - /// - /// The HTTP request to sign. - /// An object for tracking the current operation. - public void SignRequest(HttpWebRequest request, OperationContext operationContext) - { - // no op - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyAuthenticationHandler.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyAuthenticationHandler.cs deleted file mode 100644 index bb0e2061e69ad..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyAuthenticationHandler.cs +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Net; - - /// - /// Represents a handler that signs HTTP requests with a shared key. - /// - public sealed class SharedKeyAuthenticationHandler : IAuthenticationHandler - { - private readonly ICanonicalizer canonicalizer; - private readonly StorageCredentials credentials; - private readonly string accountName; - - /// - /// Initializes a new instance of the class. - /// - /// A canonicalizer that converts HTTP request data into a standard form appropriate for signing. - /// A object providing credentials for the request. - /// The name of the storage account that the HTTP request will access. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "canonicalizer", Justification = "Reviewed: Canonicalizer can be used as an identifier name.")] - public SharedKeyAuthenticationHandler(ICanonicalizer canonicalizer, StorageCredentials credentials, string resourceAccountName) - { - this.canonicalizer = canonicalizer; - this.credentials = credentials; - this.accountName = resourceAccountName; - } - - /// - /// Signs the specified HTTP request with a shared key. - /// - /// The HTTP request to sign. - /// An object for tracking the current operation. - public void SignRequest(HttpWebRequest request, OperationContext operationContext) - { - CommonUtility.AssertNotNull("request", request); - - string dateString = HttpWebUtility.ConvertDateTimeToHttpString(DateTime.UtcNow); - request.Headers.Add(Constants.HeaderConstants.Date, dateString); - - if (this.credentials.IsSharedKey) - { - string message = this.canonicalizer.CanonicalizeHttpRequest(request, this.accountName); - Logger.LogVerbose(operationContext, SR.TraceStringToSign, message); - - StorageAccountKey accountKey = this.credentials.Key; - string signature = CryptoUtility.ComputeHmac256(accountKey.KeyValue, message); - - if (!string.IsNullOrEmpty(accountKey.KeyName)) - { - request.Headers.Add(Constants.HeaderConstants.KeyNameHeader, accountKey.KeyName); - } - - request.Headers.Add( - "Authorization", - string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", this.canonicalizer.AuthorizationScheme, this.credentials.AccountName, signature)); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyLiteAuthenticationHandler.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyLiteAuthenticationHandler.cs deleted file mode 100644 index fb6afd019a4af..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Auth/Protocol/SharedKeyLiteAuthenticationHandler.cs +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Auth; - using System.Diagnostics.CodeAnalysis; - using System.Net; - - /// - /// Represents a handler that signs HTTP requests with a shared key. - /// - public sealed class SharedKeyLiteAuthenticationHandler : IAuthenticationHandler - { - private readonly SharedKeyAuthenticationHandler authenticationHandler; - - /// - /// Initializes a new instance of the class. - /// - /// A canonicalizer that converts HTTP request data into a standard form appropriate for signing. - /// A object providing credentials for the request. - /// The name of the storage account that the HTTP request will access. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "canonicalizer", Justification = "Reviewed: Canonicalizer can be used as an identifier name.")] - public SharedKeyLiteAuthenticationHandler(ICanonicalizer canonicalizer, StorageCredentials credentials, string resourceAccountName) - { - this.authenticationHandler = new SharedKeyAuthenticationHandler(canonicalizer, credentials, resourceAccountName); - } - - /// - /// Signs the specified HTTP request with a shared key. - /// - /// The HTTP request to sign. - /// An object for tracking the current operation. - public void SignRequest(HttpWebRequest request, OperationContext operationContext) - { - this.authenticationHandler.SignRequest(request, operationContext); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobReadStream.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobReadStream.cs deleted file mode 100644 index 6076eaef90d93..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobReadStream.cs +++ /dev/null @@ -1,249 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - - internal sealed class BlobReadStream : BlobReadStreamBase - { - private volatile bool readPending = false; - - /// - /// Initializes a new instance of the BlobReadStream class. - /// - /// Blob reference to read from - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - internal BlobReadStream(ICloudBlob blob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(blob, accessCondition, options, operationContext) - { - } - - /// - /// Reads a sequence of bytes from the current stream and advances the - /// position within the stream by the number of bytes read. - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// The total number of bytes read into the buffer. This can be - /// less than the number of bytes requested if that many bytes are not - /// currently available, or zero (0) if the end of the stream has been reached. - public override int Read(byte[] buffer, int offset, int count) - { -#if !SYNC - return this.EndRead(this.BeginRead(buffer, offset, count, null, null)); -#else - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - if (this.lastException != null) - { - throw this.lastException; - } - - if ((this.currentOffset == this.Length) || (count == 0)) - { - return 0; - } - - int readCount = this.ConsumeBuffer(buffer, offset, count); - if (readCount > 0) - { - return readCount; - } - - return this.DispatchReadSync(buffer, offset, count); -#endif - } - - /// - /// Begins an asynchronous read operation. - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// An optional asynchronous callback, to be called when the read is complete. - /// A user-provided object that distinguishes this particular asynchronous read request from other requests. - /// An IAsyncResult that represents the asynchronous read, which could still be pending. - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - if (this.readPending) - { - throw new InvalidOperationException(SR.BlobStreamReadPending); - } - - try - { - this.readPending = true; - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - if (this.lastException != null) - { - storageAsyncResult.OnComplete(this.lastException); - return storageAsyncResult; - } - - if ((this.currentOffset == this.Length) || (count == 0)) - { - storageAsyncResult.Result = 0; - storageAsyncResult.OnComplete(); - return storageAsyncResult; - } - - int readCount = this.ConsumeBuffer(buffer, offset, count); - if (readCount > 0) - { - storageAsyncResult.Result = readCount; - storageAsyncResult.OnComplete(); - return storageAsyncResult; - } - - this.DispatchReadAsync(storageAsyncResult, buffer, offset, count); - return storageAsyncResult; - } - catch (Exception) - { - this.readPending = false; - throw; - } - } - - /// - /// Waits for the pending asynchronous read to complete. - /// - /// The reference to the pending asynchronous request to finish. - /// The total number of bytes read into the buffer. This can be - /// less than the number of bytes requested if that many bytes are not - /// currently available, or zero (0) if the end of the stream has been reached. - public override int EndRead(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - - this.readPending = false; - storageAsyncResult.End(); - - return storageAsyncResult.Result; - } - - /// - /// Dispatches an async read operation that either reads from the cache or makes a call to - /// the server. - /// - /// The reference to the pending asynchronous request to finish. - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - private void DispatchReadAsync(StorageAsyncResult storageAsyncResult, byte[] buffer, int offset, int count) - { - storageAsyncResult.OperationState = new ArraySegment(buffer, offset, count); - - try - { - this.internalBuffer.SetLength(0); - this.blob.BeginDownloadRangeToStream( - this.internalBuffer, - this.currentOffset, - this.GetReadSize(), - this.accessCondition, - this.options, - this.operationContext, - this.DownloadRangeToStreamCallback, - storageAsyncResult); - } - catch (Exception e) - { - this.lastException = e; - throw; - } - } - - /// - /// Called when the asynchronous DownloadRangeToStream operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void DownloadRangeToStreamCallback(IAsyncResult ar) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)ar.AsyncState; - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.blob.EndDownloadRangeToStream(ar); - - ArraySegment bufferSegment = (ArraySegment)storageAsyncResult.OperationState; - this.internalBuffer.Seek(0, SeekOrigin.Begin); - storageAsyncResult.Result = this.ConsumeBuffer(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count); - } - catch (Exception e) - { - this.lastException = e; - } - - storageAsyncResult.OnComplete(this.lastException); - } - -#if SYNC - /// - /// Dispatches a sync read operation that either reads from the cache or makes a call to - /// the server. - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// Number of bytes read from the stream. - private int DispatchReadSync(byte[] buffer, int offset, int count) - { - try - { - this.internalBuffer.SetLength(0); - this.blob.DownloadRangeToStream( - this.internalBuffer, - this.currentOffset, - this.GetReadSize(), - this.accessCondition, - this.options, - this.operationContext); - - this.internalBuffer.Seek(0, SeekOrigin.Begin); - return this.ConsumeBuffer(buffer, offset, count); - } - catch (Exception e) - { - this.lastException = e; - throw; - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobWriteStream.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobWriteStream.cs deleted file mode 100644 index 12c67fd732a4a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/BlobWriteStream.cs +++ /dev/null @@ -1,709 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Threading; - -#if WINDOWS_PHONE - using System.Threading.Tasks; -#endif - - internal sealed class BlobWriteStream : BlobWriteStreamBase - { - private volatile bool flushPending = false; - - /// - /// Initializes a new instance of the BlobWriteStream class for a block blob. - /// - /// Blob reference to write to. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - internal BlobWriteStream(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(blockBlob, accessCondition, options, operationContext) - { - } - - /// - /// Initializes a new instance of the BlobWriteStream class for a page blob. - /// - /// Blob reference to write to. - /// Size of the page blob. - /// Use true if the page blob is newly created, false otherwise. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object for tracking the current operation. - internal BlobWriteStream(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(pageBlob, pageBlobSize, createNew, accessCondition, options, operationContext) - { - } - - /// - /// Sets the position within the current stream. - /// - /// A byte offset relative to the origin parameter. - /// A value of type SeekOrigin indicating the reference - /// point used to obtain the new position. - /// The new position within the current stream. - public override long Seek(long offset, SeekOrigin origin) - { - long oldOffset = this.currentOffset; - long newOffset = this.GetNewOffset(offset, origin); - - if (oldOffset != newOffset) - { - if (this.blobMD5 != null) - { - this.blobMD5.Dispose(); - this.blobMD5 = null; - } - - this.Flush(); - } - - this.currentOffset = newOffset; - this.currentPageOffset = newOffset; - return this.currentOffset; - } - - /// - /// Writes a sequence of bytes to the current stream and advances the current - /// position within this stream by the number of bytes written. - /// - /// An array of bytes. This method copies count bytes from - /// buffer to the current stream. - /// The zero-based byte offset in buffer at which to begin - /// copying bytes to the current stream. - /// The number of bytes to be written to the current stream. - public override void Write(byte[] buffer, int offset, int count) - { - this.EndWrite(this.BeginWrite(buffer, offset, count, null /* callback */, null /* state */)); - } - - /// - /// Begins an asynchronous write operation. - /// - /// An array of bytes. This method copies count bytes from - /// buffer to the current stream. - /// The zero-based byte offset in buffer at which to begin - /// copying bytes to the current stream. - /// The number of bytes to be written to the current stream. - /// An optional asynchronous callback, to be called when the write is complete. - /// A user-provided object that distinguishes this particular asynchronous write request from other requests. - /// An IAsyncResult that represents the asynchronous write, which could still be pending. - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - if (this.committed) - { - throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); - } - - if (this.blobMD5 != null) - { - this.blobMD5.UpdateHash(buffer, offset, count); - } - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - StorageAsyncResult currentAsyncResult = storageAsyncResult; - - this.currentOffset += count; - bool dispatched = false; - if (this.lastException == null) - { - while (count > 0) - { - int maxBytesToWrite = this.streamWriteSizeInBytes - (int)this.internalBuffer.Length; - int bytesToWrite = Math.Min(count, maxBytesToWrite); - - this.internalBuffer.Write(buffer, offset, bytesToWrite); - if (this.blockMD5 != null) - { - this.blockMD5.UpdateHash(buffer, offset, bytesToWrite); - } - - count -= bytesToWrite; - offset += bytesToWrite; - - if (bytesToWrite == maxBytesToWrite) - { - this.DispatchWrite(currentAsyncResult); - dispatched = true; - - // Do not use the IAsyncResult we are going to return more - // than once, as otherwise its callback will be called more - // than once. - currentAsyncResult = null; - } - } - } - - if (!dispatched) - { - storageAsyncResult.OnComplete(this.lastException); - } - - return storageAsyncResult; - } - - /// - /// Waits for the pending asynchronous write to complete. - /// - /// The reference to the pending asynchronous request to finish. - public override void EndWrite(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - - if (this.lastException != null) - { - throw this.lastException; - } - } - - /// - /// Clears all buffers for this stream and causes any buffered data to be written to the underlying blob. - /// - public override void Flush() - { - if (this.lastException != null) - { - throw this.lastException; - } - - if (this.committed) - { - throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); - } - - this.DispatchWrite(null /* asyncResult */); - this.noPendingWritesEvent.Wait(); - - if (this.lastException != null) - { - throw this.lastException; - } - } - - /// - /// Begins an asynchronous flush operation. - /// - /// An optional asynchronous callback, to be called when the flush is complete. - /// A user-provided object that distinguishes this particular asynchronous flush request from other requests. - /// An ICancellableAsyncResult that represents the asynchronous flush, which could still be pending. - public override ICancellableAsyncResult BeginFlush(AsyncCallback callback, object state) - { - if (this.committed) - { - throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); - } - - if (this.flushPending) - { - // We cannot allow more than one BeginFlush at a time, because - // RegisterWaitForSingleObject would need duplicated handles - // of noPendingWritesEvent for each call. - throw new InvalidOperationException(SR.BlobStreamFlushPending); - } - - try - { - this.flushPending = true; - this.DispatchWrite(null /* asyncResult */); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - if ((this.lastException != null) || this.noPendingWritesEvent.Wait(0)) - { - storageAsyncResult.OnComplete(this.lastException); - } - else - { - RegisteredWaitHandle waitHandle = ThreadPool.RegisterWaitForSingleObject( - this.noPendingWritesEvent.WaitHandle, - this.WaitForPendingWritesCallback, - storageAsyncResult, - -1, - true); - - storageAsyncResult.OperationState = waitHandle; - storageAsyncResult.CancelDelegate = () => - { - waitHandle.Unregister(null /* waitObject */); - storageAsyncResult.OnComplete(this.lastException); - }; - } - - return storageAsyncResult; - } - catch (Exception) - { - this.flushPending = false; - throw; - } - } - - /// - /// Waits for the pending asynchronous flush to complete. - /// - /// The reference to the pending asynchronous request to finish. - public override void EndFlush(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - this.flushPending = false; - storageAsyncResult.End(); - } - -#if WINDOWS_PHONE - /// - /// Returns a task that performs an asynchronous flush operation. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - public override Task FlushAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFlush, this.EndFlush, cancellationToken); - } -#endif - - /// - /// Called when noPendingWritesEvent is signalled indicating that there are no outstanding write requests. - /// - /// An object containing information to be used by the callback method each time it executes. - /// true if the WaitHandle timed out; false if it was signaled. - private void WaitForPendingWritesCallback(object state, bool timedOut) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)state; - storageAsyncResult.UpdateCompletedSynchronously(false); - storageAsyncResult.OnComplete(this.lastException); - - RegisteredWaitHandle waitHandle = (RegisteredWaitHandle)storageAsyncResult.OperationState; - if (waitHandle != null) - { - waitHandle.Unregister(null /* waitObject */); - } - } - - /// - /// Releases the blob resources used by the Stream. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool disposing) - { - if (!this.disposed) - { - this.disposed = true; - - if (disposing) - { - if (!this.committed) - { -#if SYNC - this.Commit(); -#else - this.EndCommit(this.BeginCommit(null, null)); -#endif - } - } - } - - base.Dispose(disposing); - } - -#if SYNC - /// - /// Clears all buffers for this stream, causes any buffered data to be written to the underlying blob, and commits the blob. - /// - public override void Commit() - { - this.Flush(); - this.committed = true; - - try - { - if (this.blockBlob != null) - { - if (this.blobMD5 != null) - { - this.blockBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - } - - this.blockBlob.PutBlockList( - this.blockList, - this.accessCondition, - this.options, - this.operationContext); - } - else - { - if (this.blobMD5 != null) - { - this.pageBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - this.pageBlob.SetProperties( - this.accessCondition, - this.options, - this.operationContext); - } - } - } - catch (Exception e) - { - this.lastException = e; - throw; - } - } -#endif - - /// - /// Begins an asynchronous commit operation. - /// - /// An optional asynchronous callback, to be called when the commit is complete. - /// A user-provided object that distinguishes this particular asynchronous commit request from other requests. - /// An ICancellableAsyncResult that represents the asynchronous commit, which could still be pending. - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "storageAsyncResult must be returned.")] - public override ICancellableAsyncResult BeginCommit(AsyncCallback callback, object state) - { - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - ICancellableAsyncResult result = this.BeginFlush(this.CommitFlushCallback, storageAsyncResult); - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Waits for the pending asynchronous commit to complete. - /// - /// The reference to the pending asynchronous request to finish. - public override void EndCommit(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - } - - /// - /// Called when the pending flush operation completes so that we can continue with the commit. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void CommitFlushCallback(IAsyncResult ar) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)ar.AsyncState; - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - this.committed = true; - - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - this.EndFlush(ar); - - if (this.blockBlob != null) - { - if (this.blobMD5 != null) - { - this.blockBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - } - - ICancellableAsyncResult result = this.blockBlob.BeginPutBlockList( - this.blockList, - this.accessCondition, - this.options, - this.operationContext, - this.PutBlockListCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = result.Cancel; - } - else - { - if (this.blobMD5 != null) - { - this.pageBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - ICancellableAsyncResult result = this.pageBlob.BeginSetProperties( - this.accessCondition, - this.options, - this.operationContext, - this.SetPropertiesCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = result.Cancel; - } - else - { - storageAsyncResult.OnComplete(); - } - } - - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - this.lastException = e; - storageAsyncResult.OnComplete(e); - } - } - } - - /// - /// Called when the block blob commit operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void PutBlockListCallback(IAsyncResult ar) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)ar.AsyncState; - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.blockBlob.EndPutBlockList(ar); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - this.lastException = e; - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Called when the page blob commit operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void SetPropertiesCallback(IAsyncResult ar) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)ar.AsyncState; - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.pageBlob.EndSetProperties(ar); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - this.lastException = e; - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Dispatches a write operation. - /// - /// The reference to the pending asynchronous request to finish. - private void DispatchWrite(StorageAsyncResult asyncResult) - { - if (this.internalBuffer.Length == 0) - { - if (asyncResult != null) - { - asyncResult.OnComplete(this.lastException); - } - - return; - } - - MultiBufferMemoryStream bufferToUpload = this.internalBuffer; - this.internalBuffer = new MultiBufferMemoryStream(this.Blob.ServiceClient.BufferManager); - bufferToUpload.Seek(0, SeekOrigin.Begin); - - string bufferMD5 = null; - if (this.blockMD5 != null) - { - bufferMD5 = this.blockMD5.ComputeHash(); - this.blockMD5.Dispose(); - this.blockMD5 = new MD5Wrapper(); - } - - if (this.blockBlob != null) - { - string blockId = this.GetCurrentBlockId(); - this.blockList.Add(blockId); - this.WriteBlock(bufferToUpload, blockId, bufferMD5, asyncResult); - } - else - { - if ((bufferToUpload.Length % Constants.PageSize) != 0) - { - this.lastException = new IOException(SR.InvalidPageSize); - throw this.lastException; - } - - long offset = this.currentPageOffset; - this.currentPageOffset += bufferToUpload.Length; - this.WritePages(bufferToUpload, offset, bufferMD5, asyncResult); - } - } - - /// - /// Starts an asynchronous PutBlock operation as soon as the parallel - /// operation semaphore becomes available. - /// - /// Data to be uploaded - /// Block ID - /// MD5 hash of the data to be uploaded - /// The reference to the pending asynchronous request to finish. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void WriteBlock(Stream blockData, string blockId, string blockMD5, StorageAsyncResult asyncResult) - { - this.noPendingWritesEvent.Increment(); - this.parallelOperationSemaphore.WaitAsync(calledSynchronously => - { - try - { - ICancellableAsyncResult result = this.blockBlob.BeginPutBlock( - blockId, - blockData, - blockMD5, - this.accessCondition, - this.options, - this.operationContext, - this.PutBlockCallback, - null /* state */); - - if (asyncResult != null) - { - // We do not need to do this inside a lock, as asyncResult is - // not returned to the user yet. - asyncResult.CancelDelegate = result.Cancel; - } - } - catch (Exception e) - { - this.lastException = e; - } - finally - { - if (asyncResult != null) - { - asyncResult.UpdateCompletedSynchronously(calledSynchronously); - asyncResult.OnComplete(this.lastException); - } - } - }); - } - - /// - /// Called when the asynchronous PutBlock operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void PutBlockCallback(IAsyncResult ar) - { - try - { - this.blockBlob.EndPutBlock(ar); - } - catch (Exception e) - { - this.lastException = e; - } - - // This must be called in a separate thread than the user's - // callback to prevent a deadlock in case the callback is blocking. - // If they are called in the same thread, this call must take - // place before the user's callback. - this.noPendingWritesEvent.Decrement(); - this.parallelOperationSemaphore.Release(); - } - - /// - /// Starts an asynchronous WritePages operation as soon as the parallel - /// operation semaphore becomes available. - /// - /// Data to be uploaded - /// Offset within the page blob - /// MD5 hash of the data to be uploaded - /// The reference to the pending asynchronous request to finish. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "If user's callback throws any exception, we want to ignore and continue.")] - private void WritePages(Stream pageData, long offset, string contentMD5, StorageAsyncResult asyncResult) - { - this.noPendingWritesEvent.Increment(); - this.parallelOperationSemaphore.WaitAsync(calledSynchronously => - { - try - { - ICancellableAsyncResult result = this.pageBlob.BeginWritePages( - pageData, - offset, - contentMD5, - this.accessCondition, - this.options, - this.operationContext, - this.WritePagesCallback, - null /* state */); - - if (asyncResult != null) - { - // We do not need to do this inside a lock, as asyncResult is - // not returned to the user yet. - asyncResult.CancelDelegate = result.Cancel; - } - } - catch (Exception e) - { - this.lastException = e; - } - finally - { - if (asyncResult != null) - { - asyncResult.UpdateCompletedSynchronously(calledSynchronously); - asyncResult.OnComplete(this.lastException); - } - } - }); - } - - /// - /// Called when the asynchronous WritePages operation completes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void WritePagesCallback(IAsyncResult ar) - { - try - { - this.pageBlob.EndWritePages(ar); - } - catch (Exception e) - { - this.lastException = e; - } - - // This must be called in a separate thread than the user's - // callback to prevent a deadlock in case the callback is blocking. - // If they are called in the same thread, this call must take - // place before the user's callback. - this.noPendingWritesEvent.Decrement(); - this.parallelOperationSemaphore.Release(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobClient.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobClient.cs deleted file mode 100644 index 803fd9186b886..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobClient.cs +++ /dev/null @@ -1,1027 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Provides a client-side logical representation of the Windows Azure Blob service. This client is used to configure and execute requests against 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 sealed partial class CloudBlobClient - { - private IAuthenticationHandler authenticationHandler; - - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - if (value != this.authenticationScheme) - { - this.authenticationScheme = value; - this.authenticationHandler = null; - } - } - } - - /// - /// Gets the authentication handler used to sign HTTP requests. - /// - /// The authentication handler. - internal IAuthenticationHandler AuthenticationHandler - { - get - { - IAuthenticationHandler result = this.authenticationHandler; - if (result == null) - { - if (this.Credentials.IsSharedKey) - { - result = new SharedKeyAuthenticationHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - result = new NoOpAuthenticationHandler(); - } - - this.authenticationHandler = result; - } - - return result; - } - } - -#if SYNC - /// - /// Returns an enumerable collection of containers whose names - /// begin with the specified prefix and that are retrieved lazily. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// An enumerable collection of containers that are retrieved lazily. - [DoesServiceRequest] - public IEnumerable ListContainers(string prefix = null, ContainerListingDetails detailsIncluded = ContainerListingDetails.None, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - return CommonUtility.LazyEnumerable( - token => this.ListContainersSegmentedCore(prefix, detailsIncluded, null /* maxResults */, (BlobContinuationToken)token, modifiedOptions, operationContext), - long.MaxValue); - } - - /// - /// Returns a result segment containing a collection of objects. - /// - /// A returned by a previous listing operation. - /// A result segment of containers. - [DoesServiceRequest] - public ContainerResultSegment ListContainersSegmented(BlobContinuationToken currentToken) - { - return this.ListContainersSegmented(null /* prefix */, ContainerListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of objects. - /// - /// The container name prefix. - /// A returned by a previous listing operation. - /// A result segment of containers. - [DoesServiceRequest] - public ContainerResultSegment ListContainersSegmented(string prefix, BlobContinuationToken currentToken) - { - return this.ListContainersSegmented(prefix, ContainerListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of containers whose names begin with the specified prefix. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A result segment of containers. - [DoesServiceRequest] - public ContainerResultSegment ListContainersSegmented(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - ResultSegment resultSegment = this.ListContainersSegmentedCore(prefix, detailsIncluded, maxResults, currentToken, modifiedOptions, operationContext); - return new ContainerResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - } - - /// - /// Returns a result segment containing a collection of containers - /// whose names begin with the specified prefix. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A result segment of containers. - private ResultSegment ListContainersSegmentedCore(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken continuationToken, BlobRequestOptions options, OperationContext operationContext) - { - return Executor.ExecuteSync( - this.ListContainersImpl(prefix, detailsIncluded, continuationToken, maxResults, options), - options.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to return a result segment containing a collection of containers. - /// - /// A continuation token returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListContainersSegmented(BlobContinuationToken continuationToken, AsyncCallback callback, object state) - { - return this.BeginListContainersSegmented(null /* prefix */, ContainerListingDetails.None, null /* maxResults */, continuationToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to return a result segment containing a collection of containers. - /// - /// The container name prefix. - /// A continuation token returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListContainersSegmented(string prefix, BlobContinuationToken continuationToken, AsyncCallback callback, object state) - { - return this.BeginListContainersSegmented(prefix, ContainerListingDetails.None, null /* maxResults */, continuationToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to return a result segment containing a collection of containers - /// whose names begin with the specified prefix. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListContainersSegmented(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken continuationToken, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - return Executor.BeginExecuteAsync( - this.ListContainersImpl(prefix, detailsIncluded, continuationToken, maxResults, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection of containers. - /// - /// An that references the pending asynchronous operation. - /// A result segment of containers. - public ContainerResultSegment EndListContainersSegmented(IAsyncResult asyncResult) - { - ResultSegment resultSegment = Executor.EndExecuteAsync>(asyncResult); - return new ContainerResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// A continuation token returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(BlobContinuationToken continuationToken) - { - return this.ListContainersSegmentedAsync(continuationToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// A continuation token returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(BlobContinuationToken continuationToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListContainersSegmented, this.EndListContainersSegmented, continuationToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// The container name prefix. - /// A continuation token returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(string prefix, BlobContinuationToken continuationToken) - { - return this.ListContainersSegmentedAsync(prefix, continuationToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// The container name prefix. - /// A continuation token returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(string prefix, BlobContinuationToken continuationToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListContainersSegmented, this.EndListContainersSegmented, prefix, continuationToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken continuationToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.ListContainersSegmentedAsync(prefix, detailsIncluded, maxResults, continuationToken, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to return a result segment containing a collection of containers. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListContainersSegmentedAsync(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken continuationToken, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListContainersSegmented, this.EndListContainersSegmented, prefix, detailsIncluded, maxResults, continuationToken, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Returns an enumerable collection of the blobs in the container that are retrieved lazily. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of objects that implement and are retrieved lazily. - [DoesServiceRequest] - public IEnumerable ListBlobs(string prefix, bool useFlatBlobListing = false, BlobListingDetails blobListingDetails = BlobListingDetails.None, BlobRequestOptions options = null, OperationContext operationContext = null) - { - string containerName; - string listingPrefix; - CloudBlobClient.ParseUserPrefix(prefix, out containerName, out listingPrefix); - - CloudBlobContainer container = this.GetContainerReference(containerName); - return container.ListBlobs(listingPrefix, useFlatBlobListing, blobListingDetails, options, operationContext); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix, including the container name. - /// A returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmented(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix, including the container name. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - string containerName; - string listingPrefix; - CloudBlobClient.ParseUserPrefix(prefix, out containerName, out listingPrefix); - - CloudBlobContainer container = this.GetContainerReference(containerName); - return container.ListBlobsSegmented(listingPrefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext); - } - -#endif - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix, including the container name. - /// A returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, BlobContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListBlobsSegmented(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix, including the container name. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - string containerName; - string listingPrefix; - CloudBlobClient.ParseUserPrefix(prefix, out containerName, out listingPrefix); - - CloudBlobContainer container = this.GetContainerReference(containerName); - StorageAsyncResult result = new StorageAsyncResult(callback, state); - ICancellableAsyncResult asyncResult = container.BeginListBlobsSegmented( - listingPrefix, - useFlatBlobListing, - blobListingDetails, - maxResults, - currentToken, - options, - operationContext, - ar => - { - result.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - result.Result = container.EndListBlobsSegmented(ar); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - }, - null /* state */); - - result.CancelDelegate = asyncResult.Cancel; - return result; - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// An that references the pending asynchronous operation. - /// A result segment containing objects that implement . - public BlobResultSegment EndListBlobsSegmented(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - return result.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix, including the container name. - /// A returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(prefix, currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// A returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, prefix, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.ListBlobsSegmentedAsync(prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets a reference to a blob from the service. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A reference to the blob. - [DoesServiceRequest] - public ICloudBlob GetBlobReferenceFromServer(Uri blobUri, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("blobUri", blobUri); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - return Executor.ExecuteSync( - this.GetBlobReferenceImpl(blobUri, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to get a reference to a blob from the service. - /// - /// The URI of the blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetBlobReferenceFromServer(Uri blobUri, AsyncCallback callback, object state) - { - return this.BeginGetBlobReferenceFromServer(blobUri, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get a reference to a blob from the service. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetBlobReferenceFromServer(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("blobUri", blobUri); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - return Executor.BeginExecuteAsync( - this.GetBlobReferenceImpl(blobUri, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to get a reference to a blob from the service. - /// - /// An that references the pending asynchronous operation. - /// A reference to the blob. - public ICloudBlob EndGetBlobReferenceFromServer(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that gets a reference to a blob from the service. - /// - /// The URI of the blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(Uri blobUri) - { - return this.GetBlobReferenceFromServerAsync(blobUri, CancellationToken.None); - } - - /// - /// Returns a task that gets a reference to a blob from the service. - /// - /// The URI of the blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(Uri blobUri, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetBlobReferenceFromServer, this.EndGetBlobReferenceFromServer, blobUri, cancellationToken); - } - - /// - /// Returns a object that gets a reference to a blob from the service. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.GetBlobReferenceFromServerAsync(blobUri, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that gets a reference to a blob from the service. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetBlobReferenceFromServer, this.EndGetBlobReferenceFromServer, blobUri, accessCondition, options, operationContext, cancellationToken); - } -#endif - - /// - /// Core implementation for the ListContainers method. - /// - /// The container prefix. - /// The details included. - /// The continuation token. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A object that specifies additional options for the request. - /// A that lists the containers. - private RESTCommand> ListContainersImpl(string prefix, ContainerListingDetails detailsIncluded, BlobContinuationToken currentToken, int? maxResults, BlobRequestOptions options) - { - ListingContext listingContext = new ListingContext(prefix, maxResults) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.Credentials, this.BaseUri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.List(uri, serverTimeout, listingContext, detailsIncluded, ctx); - getCmd.SignRequest = this.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ListContainersResponse listContainersResponse = new ListContainersResponse(cmd.ResponseStream); - List containersList = new List( - listContainersResponse.Containers.Select(item => new CloudBlobContainer(item.Properties, item.Metadata, item.Name, this))); - BlobContinuationToken continuationToken = null; - if (listContainersResponse.NextMarker != null) - { - continuationToken = new BlobContinuationToken() - { - NextMarker = listContainersResponse.NextMarker, - }; - } - - return new ResultSegment(containersList) - { - ContinuationToken = continuationToken, - }; - }; - - return getCmd; - } - - /// - /// Implements the FetchAttributes method. The attributes are updated immediately. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand GetBlobReferenceImpl(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options) - { - // If the blob Uri contains SAS credentials, we need to use those - // credentials instead of this service client's stored credentials. - StorageCredentials parsedCredentials; - DateTimeOffset? parsedSnapshot; - blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot); - CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.BaseUri, parsedCredentials) : this; - - RESTCommand getCmd = new RESTCommand(client.Credentials, blobUri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, parsedSnapshot, accessCondition, ctx); - getCmd.SignRequest = client.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - BlobAttributes attributes = new BlobAttributes() - { - Uri = blobUri, - SnapshotTime = parsedSnapshot, - }; - - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - - switch (attributes.Properties.BlobType) - { - case BlobType.BlockBlob: - return new CloudBlockBlob(attributes, client); - - case BlobType.PageBlob: - return new CloudPageBlob(attributes, client); - - default: - throw new InvalidOperationException(); - } - }; - - return getCmd; - } - - #region Analytics - - /// - /// Begins an asynchronous operation to get the properties of the blob service. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(AsyncCallback callback, object state) - { - return this.BeginGetServiceProperties(null /* requestOptions */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get the properties of the blob service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(BlobRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.GetServicePropertiesImpl(requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to get the properties of the blob service. - /// - /// The result returned from a prior call to - /// BeginGetServiceProperties - /// . - /// The blob service properties. - public ServiceProperties EndGetServiceProperties(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get the properties of the blob service. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the blob service. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the blob service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(BlobRequestOptions requestOptions, OperationContext operationContext) - { - return this.GetServicePropertiesAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the blob service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(BlobRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, requestOptions, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets the properties of the blob service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// The blob service properties. - [DoesServiceRequest] - public ServiceProperties GetServiceProperties(BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.ExecuteSync( - this.GetServicePropertiesImpl(requestOptions), - requestOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set the properties of the blob service. - /// - /// The blob service properties. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, AsyncCallback callback, object state) - { - return this.BeginSetServiceProperties(properties, null /* requestOptions */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set the properties of the blob service. - /// - /// The blob service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, BlobRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.SetServicePropertiesImpl(properties, requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to set the properties of the blob service. - /// - /// The result returned from a prior call to - /// BeginSetServiceProperties . - public void EndSetServiceProperties(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that gets the properties of the blob service. - /// - /// The blob service properties. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, CancellationToken.None); - } - - /// - /// Returns a task that gets the properties of the blob service. - /// - /// The blob service properties. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, cancellationToken); - } - - /// - /// Returns a task that gets the properties of the blob service. - /// - /// The blob service properties. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, BlobRequestOptions requestOptions, OperationContext operationContext) - { - return this.SetServicePropertiesAsync(properties, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that gets the properties of the blob service. - /// - /// The blob service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, BlobRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, requestOptions, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the properties of the blob service. - /// - /// The blob service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetServiceProperties(ServiceProperties properties, BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - Executor.ExecuteSync( - this.SetServicePropertiesImpl(properties, requestOptions), - requestOptions.RetryPolicy, - operationContext); - } -#endif - - private RESTCommand GetServicePropertiesImpl(BlobRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequestDelegate = BlobHttpWebRequestFactory.GetServiceProperties; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.RetrieveResponseStream = true; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - retCmd.PostProcessResponse = - (cmd, resp, ctx) => BlobHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions) - { - MultiBufferMemoryStream str = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(str); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - str.Seek(0, SeekOrigin.Begin); - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.SendStream = str; - retCmd.BuildRequestDelegate = BlobHttpWebRequestFactory.SetServiceProperties; - retCmd.RecoveryAction = RecoveryActions.RewindStream; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobContainer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobContainer.cs deleted file mode 100644 index e1debc4754f52..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobContainer.cs +++ /dev/null @@ -1,2778 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a container in the Windows Azure Blob service. - /// - /// Containers hold directories, which are encapsulated as objects, and directories hold block blobs and page blobs. Directories can also contain sub-directories. - public sealed partial class CloudBlobContainer - { -#if SYNC - /// - /// Creates the container. - /// - /// A object that specifies additional options for the request. - /// An 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. - [DoesServiceRequest] - public void Create(BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - this.Create(BlobContainerPublicAccessType.Off, requestOptions, operationContext); - } - - /// - /// Creates the container and specifies the level of access to the container's data. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An 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. - [DoesServiceRequest] - public void Create(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.CreateContainerImpl(modifiedOptions, accessType), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to create a container. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(AsyncCallback callback, object state) - { - return this.BeginCreate(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a container. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginCreate(BlobContainerPublicAccessType.Off, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to create a container and specify the level of access to the container's data. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.CreateContainerImpl(modifiedOptions, accessType), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to create a container. - /// - /// An that references the pending asynchronous operation. - public void EndCreate(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that creates a container. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync() - { - return this.CreateAsync(CancellationToken.None); - } - - /// - /// Returns a task that creates a container. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, cancellationToken); - } - - /// - /// Returns a task that creates a container. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateAsync(accessType, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that creates a container and specifies the level of access to the container's data. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, accessType, options, operationContext, cancellationToken); - } -#endif -#if SYNC - /// - /// Creates the container if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container did not already exist and was created; otherwise false. - [DoesServiceRequest] - public bool CreateIfNotExists(BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - return this.CreateIfNotExists(BlobContainerPublicAccessType.Off, requestOptions, operationContext); - } - - /// - /// Creates the container if it does not already exist and specifies whether the container or its blobs are publicly accessible. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container did not already exist and was created; otherwise false. - [DoesServiceRequest] - public bool CreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - - if (exists) - { - return false; - } - - try - { - this.Create(accessType, modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } -#endif - - /// - /// Begins an asynchronous request to create the container if it does not already exist. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(AsyncCallback callback, object state) - { - return this.BeginCreateIfNotExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to create the container if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginCreateIfNotExists(BlobContainerPublicAccessType.Off, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous request to create the container if it does not already exist. - /// - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - this.CreateIfNotExistsHandler(accessType, modifiedOptions, operationContext, storageAsyncResult); - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] - private void CreateIfNotExistsHandler(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult savedExistsResult = this.BeginExists( - options, - operationContext, - existsResult => - { - storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - bool exists = this.EndExists(existsResult); - if (exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - return; - } - - ICancellableAsyncResult savedCreateResult = this.BeginCreate( - accessType, - options, - operationContext, - createResult => - { - storageAsyncResult.UpdateCompletedSynchronously(createResult.CompletedSynchronously); - storageAsyncResult.CancelDelegate = null; - try - { - this.EndCreate(createResult); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerAlreadyExists)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedCreateResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Returns the result of an asynchronous request to create the container if it does not already exist. - /// - /// An that references the pending asynchronous operation. - /// true if the container did not already exist and was created; otherwise, false. - public bool EndCreateIfNotExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, cancellationToken); - } - - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateIfNotExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateIfNotExistsAsync(accessType, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that creates the container if it does not already exist. - /// - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, accessType, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void Delete(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.DeleteContainerImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to delete a container. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state) - { - return this.BeginDelete(null /* accessCondition */, null /* options */, null /*operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.DeleteContainerImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to delete a container. - /// - /// An that references the pending asynchronous operation. - public void EndDelete(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that deletes the container. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync() - { - return this.DeleteAsync(CancellationToken.None); - } - - /// - /// Returns a task that deletes the container. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, cancellationToken); - } - - /// - /// Returns a task that deletes the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that deletes the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the container if it already exists. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container did not already exist and was created; otherwise false. - [DoesServiceRequest] - public bool DeleteIfExists(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - if (!exists) - { - return false; - } - - try - { - this.Delete(accessCondition, modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } -#endif - - /// - /// Begins an asynchronous request to delete the container if it already exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state) - { - return this.BeginDeleteIfExists(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to delete the container if it already exists. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - this.DeleteIfExistsHandler(accessCondition, modifiedOptions, operationContext, storageAsyncResult); - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] - private void DeleteIfExistsHandler(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult savedExistsResult = this.BeginExists( - options, - operationContext, - existsResult => - { - storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - bool exists = this.EndExists(existsResult); - if (!exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - return; - } - - ICancellableAsyncResult savedDeleteResult = this.BeginDelete( - accessCondition, - options, - operationContext, - deleteResult => - { - storageAsyncResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously); - storageAsyncResult.CancelDelegate = null; - try - { - this.EndDelete(deleteResult); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.ContainerNotFound)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedDeleteResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Returns the result of an asynchronous request to delete the container if it already exists. - /// - /// An that references the pending asynchronous operation. - /// true if the container did not already exist and was created; otherwise, false. - public bool EndDeleteIfExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that deletes the container if it already exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that deletes the container if it already exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, cancellationToken); - } - - /// - /// Returns a task that deletes the container if it already exists. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteIfExistsAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that deletes the container if it already exists. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets a reference to a blob in this container. - /// - /// The name of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A reference to the blob. - [DoesServiceRequest] - public ICloudBlob GetBlobReferenceFromServer(string blobName, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - Uri blobUri = NavigationHelper.AppendPathToUri(this.Uri, blobName); - - return this.ServiceClient.GetBlobReferenceFromServer(blobUri, accessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to get a reference to a blob in this container. - /// - /// The name of the blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetBlobReferenceFromServer(string blobName, AsyncCallback callback, object state) - { - return this.BeginGetBlobReferenceFromServer(blobName, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get a reference to a blob in this container. - /// - /// The name of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetBlobReferenceFromServer(string blobName, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - Uri blobUri = NavigationHelper.AppendPathToUri(this.Uri, blobName); - - return this.ServiceClient.BeginGetBlobReferenceFromServer(blobUri, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to get a reference to a blob in this container. - /// - /// An that references the pending asynchronous operation. - /// A reference to the blob. - public ICloudBlob EndGetBlobReferenceFromServer(IAsyncResult asyncResult) - { - return this.ServiceClient.EndGetBlobReferenceFromServer(asyncResult); - } - -#if TASK - /// - /// Returns a task that gets a reference to a blob in this container. - /// - /// The name of the blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(string blobName) - { - return this.GetBlobReferenceFromServerAsync(blobName, CancellationToken.None); - } - - /// - /// Returns a task that gets a reference to a blob in this container. - /// - /// The name of the blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(string blobName, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetBlobReferenceFromServer, this.EndGetBlobReferenceFromServer, blobName, cancellationToken); - } - - /// - /// Returns a task that gets a reference to a blob in this container. - /// - /// The name of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(string blobName, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.GetBlobReferenceFromServerAsync(blobName, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that gets a reference to a blob in this container. - /// - /// The name of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetBlobReferenceFromServerAsync(string blobName, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetBlobReferenceFromServer, this.EndGetBlobReferenceFromServer, blobName, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Returns an enumerable collection of the blobs in the container that are retrieved lazily. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of objects that implement and are retrieved lazily. - [DoesServiceRequest] - public IEnumerable ListBlobs(string prefix = null, bool useFlatBlobListing = false, BlobListingDetails blobListingDetails = BlobListingDetails.None, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return CommonUtility.LazyEnumerable( - token => this.ListBlobsSegmentedCore(prefix, useFlatBlobListing, blobListingDetails, null /* maxResults */, (BlobContinuationToken)token, modifiedOptions, operationContext), - long.MaxValue); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmented(null /* prefix */, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmented(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - ResultSegment resultSegment = this.ListBlobsSegmentedCore(prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, modifiedOptions, operationContext); - return new BlobResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - private ResultSegment ListBlobsSegmentedCore(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return Executor.ExecuteSync( - this.ListBlobsImpl(prefix, maxResults, useFlatBlobListing, blobListingDetails, options, currentToken), - options.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// A continuation token returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(BlobContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListBlobsSegmented(null /* prefix */, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// A continuation token returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, BlobContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListBlobsSegmented(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ListBlobsImpl(prefix, maxResults, useFlatBlobListing, blobListingDetails, modifiedOptions, currentToken), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection of blob items - /// in the container. - /// - /// An that references the pending asynchronous operation. - /// A result segment containing objects that implement . - public BlobResultSegment EndListBlobsSegmented(IAsyncResult asyncResult) - { - ResultSegment resultSegment = Executor.EndExecuteAsync>(asyncResult); - return new BlobResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - } - -#if TASK - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// A continuation token returned by a previous listing operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// A continuation token returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(BlobContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, currentToken, cancellationToken); - } - - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// A continuation token returned by a previous listing operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(prefix, currentToken, CancellationToken.None); - } - - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// A continuation token returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, prefix, currentToken, cancellationToken); - } - - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.ListBlobsSegmentedAsync(prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that returns a result segment containing a collection of blob items - /// in the container. - /// - /// The blob name prefix. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets permissions for the container. - /// - /// The permissions to apply to the container. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetPermissions(BlobContainerPermissions permissions, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.SetPermissionsImpl(permissions, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to set permissions for the container. - /// - /// The permissions to apply to the container. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(BlobContainerPermissions permissions, AsyncCallback callback, object state) - { - return this.BeginSetPermissions(permissions, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to set permissions for the container. - /// - /// The permissions to apply to the container. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(BlobContainerPermissions permissions, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.SetPermissionsImpl(permissions, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the result of an asynchronous request to set permissions for the container. - /// - /// An that references the pending asynchronous operation. - public void EndSetPermissions(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that sets permissions for the container. - /// - /// The permissions to apply to the container. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(BlobContainerPermissions permissions) - { - return this.SetPermissionsAsync(permissions, CancellationToken.None); - } - - /// - /// Returns a task that sets permissions for the container. - /// - /// The permissions to apply to the container. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(BlobContainerPermissions permissions, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, cancellationToken); - } - - /// - /// Returns a task that sets permissions for the container. - /// - /// The permissions to apply to the container. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(BlobContainerPermissions permissions, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetPermissionsAsync(permissions, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that sets permissions for the container. - /// - /// The permissions to apply to the container. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(BlobContainerPermissions permissions, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets the permissions settings for the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The container's permissions. - [DoesServiceRequest] - public BlobContainerPermissions GetPermissions(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.ExecuteSync( - this.GetPermissionsImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to get the permissions settings for the container. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(AsyncCallback callback, object state) - { - return this.BeginGetPermissions(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to get the permissions settings for the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.GetPermissionsImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to get the permissions settings for the container. - /// - /// An that references the pending asynchronous operation. - /// The container's permissions. - public BlobContainerPermissions EndGetPermissions(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that gets the permissions settings for the container. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync() - { - return this.GetPermissionsAsync(CancellationToken.None); - } - - /// - /// Returns a task that gets the permissions settings for the container. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, cancellationToken); - } - - /// - /// Returns a task that gets the permissions settings for the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.GetPermissionsAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that gets the permissions settings for the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Checks whether the container exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container exists. - [DoesServiceRequest] - public bool Exists(BlobRequestOptions requestOptions = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this.ServiceClient); - return Executor.ExecuteSync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - /// - /// Begins an asynchronous request to check whether the container exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(AsyncCallback callback, object state) - { - return this.BeginExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to check whether the container exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to check whether the container exists. - /// - /// An that references the pending asynchronous operation. - /// true if the container exists. - public bool EndExists(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that checks whether the container exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync() - { - return this.ExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that checks whether the container exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, cancellationToken); - } - - /// - /// Returns a task that checks whether the container exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.ExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that checks whether the container exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Retrieves the container's attributes. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void FetchAttributes(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.FetchAttributesImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to retrieve the container's attributes. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AsyncCallback callback, object state) - { - return this.BeginFetchAttributes(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to retrieve the container's attributes. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.FetchAttributesImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to retrieve the container's attributes. - /// - /// An that references the pending asynchronous operation. - public void EndFetchAttributes(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that retrieves the container's attributes. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync() - { - return this.FetchAttributesAsync(CancellationToken.None); - } - - /// - /// Returns a task that retrieves the container's attributes. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, cancellationToken); - } - - /// - /// Returns a task that retrieves the container's attributes. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.FetchAttributesAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that retrieves the container's attributes. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the container's user-defined metadata. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetMetadata(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.SetMetadataImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set user-defined metadata on the container. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AsyncCallback callback, object state) - { - return this.BeginSetMetadata(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set user-defined metadata on the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.SetMetadataImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous request operation to set user-defined metadata on the container. - /// - /// An that references the pending asynchronous operation. - public void EndSetMetadata(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that sets container's user-defined metadata. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync() - { - return this.SetMetadataAsync(CancellationToken.None); - } - - /// - /// Returns a task that sets container's user-defined metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, cancellationToken); - } - - /// - /// Returns a task that sets container's user-defined metadata. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetMetadataAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that sets container's user-defined metadata. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public string AcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.ExecuteSync( - this.AcquireLeaseImpl(leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to acquire a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AsyncCallback callback, object state) - { - return this.BeginAcquireLease(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to acquire a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.AcquireLeaseImpl(leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to acquire a lease on this container. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The ID of the acquired lease. - public string EndAcquireLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, CancellationToken.None); - } - - /// - /// Returns a task that acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, cancellationToken); - } - - /// - /// Returns a task that acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void RenewLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.RenewLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to renew a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginRenewLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to renew a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.RenewLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to renew a lease on this container. - /// - /// An IAsyncResult that references the pending asynchronous operation. - public void EndRenewLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.RenewLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public string ChangeLease(string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.ExecuteSync( - this.ChangeLeaseImpl(proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to change the lease on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginChangeLease(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to change the lease on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ChangeLeaseImpl(proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to change the lease on this container. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The new lease ID. - public string EndChangeLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, cancellationToken); - } - - /// - /// Returns a task that changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void ReleaseLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - Executor.ExecuteSync( - this.ReleaseLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to release the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginReleaseLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to release the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ReleaseLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to release the lease on this container. - /// - /// An IAsyncResult that references the pending asynchronous operation. - public void EndReleaseLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ReleaseLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public TimeSpan BreakLease(TimeSpan? breakPeriod = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.ExecuteSync( - this.BreakLeaseImpl(breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to break the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AsyncCallback callback, object state) - { - return this.BeginBreakLease(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to break the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.BreakLeaseImpl(breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to break the current lease on this container. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// A representing the amount of time before the lease ends, to the second. - public TimeSpan EndBreakLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, CancellationToken.None); - } - - /// - /// Returns a task that breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, cancellationToken); - } - - /// - /// Returns a task that breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.BreakLeaseAsync(breakPeriod, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, accessCondition, options, operationContext, cancellationToken); - } -#endif - - /// - /// Generates a RESTCommand for acquiring a lease. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. This parameter must not be null. - /// A RESTCommand implementing the acquire lease operation. - internal RESTCommand AcquireLeaseImpl(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - int leaseDuration = -1; - if (leaseTime.HasValue) - { - CommonUtility.AssertInBounds("leaseTime", leaseTime.Value, TimeSpan.FromSeconds(1), TimeSpan.MaxValue); - leaseDuration = (int)leaseTime.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a RESTCommand for renewing a lease. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation, including the current lease ID. - /// This cannot be null. - /// A RESTCommand implementing the renew lease operation. - internal RESTCommand RenewLeaseImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDRenewing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a RESTCommand for changing a lease ID. - /// - /// The proposed new lease ID. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation, including the current lease ID. This cannot be null. - /// A RESTCommand implementing the change lease ID operation. - internal RESTCommand ChangeLeaseImpl(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - CommonUtility.AssertNotNull("proposedLeaseId", proposedLeaseId); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDChanging, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Change, proposedLeaseId, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a RESTCommand for releasing a lease. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation, including the current lease ID. - /// This cannot be null. - /// A RESTCommand implementing the release lease operation. - internal RESTCommand ReleaseLeaseImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a RESTCommand for breaking a lease. - /// - /// The amount of time to allow the lease to remain, rounded down to seconds. - /// If null, the break period is the remainder of the current lease, or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// The options for this operation. Cannot be null. - /// A RESTCommand implementing the break lease operation. - internal RESTCommand BreakLeaseImpl(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options) - { - int? breakSeconds = null; - if (breakPeriod.HasValue) - { - CommonUtility.AssertInBounds("breakPeriod", breakPeriod.Value, TimeSpan.Zero, TimeSpan.MaxValue); - breakSeconds = (int)breakPeriod.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); - - int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); - if (!remainingLeaseTime.HasValue) - { - // Unexpected result from service. - throw new StorageException(cmd.CurrentResult, SR.LeaseTimeNotReceived, null /* inner */); - } - - return TimeSpan.FromSeconds(remainingLeaseTime.Value); - }; - - return putCmd; - } - - /// - /// Implementation for the Create method. - /// - /// A object that specifies additional options for the request. - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A that creates the container. - private RESTCommand CreateContainerImpl(BlobRequestOptions options, BlobContainerPublicAccessType accessType) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Create(uri, serverTimeout, ctx, accessType); - putCmd.SetHeaders = (r, ctx) => ContainerHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Delete method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that deletes the container. - private RESTCommand DeleteContainerImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Delete(uri, serverTimeout, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the FetchAttributes method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand FetchAttributesImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.GetProperties(uri, serverTimeout, accessCondition, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implementation for the Exists method. - /// - /// A object that specifies additional options for the request. - /// A that checks existence. - private RESTCommand ExistsImpl(BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.GetProperties(uri, serverTimeout, null /* accessCondition */, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return true; - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand SetMetadataImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.SetMetadata(uri, serverTimeout, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => ContainerHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetPermissions method. - /// - /// The permissions to set. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand SetPermissionsImpl(BlobContainerPermissions acl, AccessCondition accessCondition, BlobRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - BlobRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.SetAcl(uri, serverTimeout, acl.PublicAccess, accessCondition, ctx); - putCmd.SendStream = memoryStream; - putCmd.RecoveryAction = RecoveryActions.RewindStream; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetPermissionsImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - BlobContainerPermissions containerAcl = null; - - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.GetAcl(uri, serverTimeout, accessCondition, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - containerAcl = new BlobContainerPermissions() - { - PublicAccess = ContainerHttpResponseParsers.GetAcl(resp), - }; - return containerAcl; - }; - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ContainerHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, containerAcl); - this.ParseSizeAndLastModified(resp); - return containerAcl; - }; - - return getCmd; - } - - /// - /// Selects the protocol response. - /// - /// The protocol item. - /// The parsed . - private IListBlobItem SelectListBlobItem(IListBlobEntry protocolItem) - { - ListBlobEntry blob = protocolItem as ListBlobEntry; - if (blob != null) - { - BlobAttributes attributes = blob.Attributes; - if (attributes.Properties.BlobType == BlobType.BlockBlob) - { - return new CloudBlockBlob(attributes, this.ServiceClient); - } - else if (attributes.Properties.BlobType == BlobType.PageBlob) - { - return new CloudPageBlob(attributes, this.ServiceClient); - } - else - { - throw new InvalidOperationException(SR.InvalidBlobListItem); - } - } - - ListBlobPrefixEntry blobPrefix = protocolItem as ListBlobPrefixEntry; - if (blobPrefix != null) - { - return this.GetDirectoryReference(blobPrefix.Name); - } - - throw new InvalidOperationException(SR.InvalidBlobListItem); - } - - /// - /// Core implementation of the ListBlobs method. - /// - /// The blob prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A object that specifies additional options for the request. - /// A continuation token returned by a previous listing operation. - /// A that lists the blobs. - private RESTCommand> ListBlobsImpl(string prefix, int? maxResults, bool useFlatBlobListing, BlobListingDetails blobListingDetails, BlobRequestOptions options, BlobContinuationToken currentToken) - { - if (!useFlatBlobListing - && (blobListingDetails & BlobListingDetails.Snapshots) == BlobListingDetails.Snapshots) - { - throw new ArgumentException(SR.ListSnapshotsWithDelimiterError, "blobListingDetails"); - } - - string delimiter = useFlatBlobListing ? null : this.ServiceClient.DefaultDelimiter; - BlobListingContext listingContext = new BlobListingContext(prefix, maxResults, delimiter, blobListingDetails) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.ListBlobs(uri, serverTimeout, listingContext, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ListBlobsResponse listBlobsResponse = new ListBlobsResponse(cmd.ResponseStream); - List blobList = new List( - listBlobsResponse.Blobs.Select(item => this.SelectListBlobItem(item))); - BlobContinuationToken continuationToken = null; - if (listBlobsResponse.NextMarker != null) - { - continuationToken = new BlobContinuationToken() - { - NextMarker = listBlobsResponse.NextMarker, - }; - } - - return new ResultSegment(blobList) - { - ContinuationToken = continuationToken, - }; - }; - - return getCmd; - } - - /// - /// Retrieve ETag and LastModified date time from response. - /// - /// The response to parse. - private void ParseSizeAndLastModified(HttpWebResponse response) - { - BlobContainerProperties parsedProperties = ContainerHttpResponseParsers.GetProperties(response); - this.Properties.ETag = parsedProperties.ETag; - this.Properties.LastModified = parsedProperties.LastModified; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobDirectory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobDirectory.cs deleted file mode 100644 index bbda6e590239e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobDirectory.cs +++ /dev/null @@ -1,187 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a virtual directory of blobs, designated by a delimiter character. - /// - /// Containers, which are encapsulated as objects, hold directories, and directories hold block blobs and page blobs. Directories can also contain sub-directories. - public sealed partial class CloudBlobDirectory - { -#if SYNC - /// - /// Returns an enumerable collection of the blobs in the virtual directory that are retrieved lazily. - /// - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of objects that implement and are retrieved lazily. - [DoesServiceRequest] - public IEnumerable ListBlobs(bool useFlatBlobListing = false, BlobListingDetails blobListingDetails = BlobListingDetails.None, BlobRequestOptions options = null, OperationContext operationContext = null) - { - return this.Container.ListBlobs(this.Prefix, useFlatBlobListing, blobListingDetails, options, operationContext); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmented(false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public BlobResultSegment ListBlobsSegmented(bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.Container.ListBlobsSegmented(this.Prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// A continuation token returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(BlobContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListBlobsSegmented(false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListBlobsSegmented(bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.Container.BeginListBlobsSegmented(this.Prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// An that references the pending asynchronous operation. - /// A result segment containing objects that implement . - public BlobResultSegment EndListBlobsSegmented(IAsyncResult asyncResult) - { - return this.Container.EndListBlobsSegmented(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// A continuation token returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// A continuation token returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(BlobContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.ListBlobsSegmentedAsync(useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of blob items - /// in the virtual directory. - /// - /// Specifies whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListBlobsSegmentedAsync(bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListBlobsSegmented, this.EndListBlobsSegmented, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, cancellationToken); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobSharedImpl.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobSharedImpl.cs deleted file mode 100644 index bc452aaaa45db..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobSharedImpl.cs +++ /dev/null @@ -1,587 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - - internal static class CloudBlobSharedImpl - { - /// - /// Called when the asynchronous operation to commit the blob started by UploadFromStream finishes. - /// - /// The result of the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - internal static void BlobOutputStreamCommitCallback(IAsyncResult result) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)result.AsyncState; - CloudBlobStream blobStream = (CloudBlobStream)storageAsyncResult.OperationState; - storageAsyncResult.UpdateCompletedSynchronously(result.CompletedSynchronously); - - try - { - blobStream.EndCommit(result); - blobStream.Dispose(); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Implements getting the stream without specifying a range. - /// - /// The blob. - /// The attributes. - /// The destination stream. - /// The offset. - /// The length. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that gets the stream. - /// - internal static RESTCommand GetBlobImpl(ICloudBlob blob, BlobAttributes attributes, Stream destStream, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) - { - string lockedETag = null; - AccessCondition lockedAccessCondition = null; - - bool isRangeGet = offset.HasValue; - bool arePropertiesPopulated = false; - string storedMD5 = null; - - long startingOffset = offset.HasValue ? offset.Value : 0; - long? startingLength = length; - long? validateLength = null; - - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.DestinationStream = destStream; - getCmd.CalculateMd5ForResponseStream = !options.DisableContentMD5Validation.Value; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => - BlobHttpWebRequestFactory.Get(uri, serverTimeout, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value, accessCondition, ctx); - getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.RecoveryAction = (cmd, ex, ctx) => - { - if ((lockedAccessCondition == null) && !string.IsNullOrEmpty(lockedETag)) - { - lockedAccessCondition = AccessCondition.GenerateIfMatchCondition(lockedETag); - if (accessCondition != null) - { - lockedAccessCondition.LeaseId = accessCondition.LeaseId; - } - } - - if (cmd.StreamCopyState != null) - { - offset = startingOffset + cmd.StreamCopyState.Length; - if (startingLength.HasValue) - { - length = startingLength.Value - cmd.StreamCopyState.Length; - } - } - - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, context) => - BlobHttpWebRequestFactory.Get(uri, serverTimeout, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value && !arePropertiesPopulated, lockedAccessCondition ?? accessCondition, context); - }; - - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(offset.HasValue ? HttpStatusCode.PartialContent : HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - if (!arePropertiesPopulated) - { - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, isRangeGet); - storedMD5 = resp.Headers[HttpResponseHeader.ContentMd5]; - - if (!options.DisableContentMD5Validation.Value && - options.UseTransactionalMD5.Value && - string.IsNullOrEmpty(storedMD5)) - { - throw new StorageException( - cmd.CurrentResult, - SR.MD5NotPresentError, - null) - { - IsRetryable = false - }; - } - - lockedETag = attributes.Properties.ETag; - if (resp.ContentLength >= 0) - { - validateLength = resp.ContentLength; - } - - arePropertiesPopulated = true; - } - - return NullType.Value; - }; - - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - HttpResponseParsers.ValidateResponseStreamMd5AndLength(validateLength, storedMD5, cmd); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implements the FetchAttributes method. The attributes are updated immediately. - /// - /// The blob. - /// The attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that fetches the attributes. - /// - internal static RESTCommand FetchAttributesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, accessCondition, ctx); - getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implementation for the Exists method. - /// - /// The blob. - /// The attributes. - /// An object that specifies additional options for the request. - /// - /// A that checks existence. - /// - internal static RESTCommand ExistsImpl(ICloudBlob blob, BlobAttributes attributes, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetProperties(uri, serverTimeout, attributes.SnapshotTime, null /* accessCondition */, ctx); - getCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - return true; - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// The blob. - /// The attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that sets the metadata. - /// - internal static RESTCommand SetMetadataImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.SetMetadata(uri, serverTimeout, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetProperties method. - /// - /// The blob. - /// The attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that sets the properties. - /// - internal static RESTCommand SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.SetProperties(uri, serverTimeout, attributes.Properties, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implements the DeleteBlob method. - /// - /// The blob. - /// The attributes. - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that deletes the blob. - /// - internal static RESTCommand DeleteBlobImpl(ICloudBlob blob, BlobAttributes attributes, DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand deleteCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - deleteCmd.ApplyRequestOptions(options); - deleteCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Delete(uri, serverTimeout, attributes.SnapshotTime, deleteSnapshotsOption, accessCondition, ctx); - deleteCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - - return deleteCmd; - } - - /// - /// Generates a for acquiring a lease. - /// - /// The blob. - /// The attributes. - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A implementing the acquire lease operation. - /// - internal static RESTCommand AcquireLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - int leaseDuration = -1; - if (leaseTime.HasValue) - { - CommonUtility.AssertInBounds("leaseTime", leaseTime.Value, TimeSpan.FromSeconds(1), TimeSpan.MaxValue); - leaseDuration = (int)leaseTime.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a for renewing a lease. - /// - /// The blob. - /// The attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A implementing the renew lease operation. - /// - /// accessCondition - internal static RESTCommand RenewLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDRenewing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a for changing a lease ID. - /// - /// The blob. - /// The attributes. - /// The proposed new lease ID. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A implementing the change lease ID operation. - /// - /// accessCondition - internal static RESTCommand ChangeLeaseImpl(ICloudBlob blob, BlobAttributes attributes, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - CommonUtility.AssertNotNull("proposedLeaseId", proposedLeaseId); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDChanging, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Change, proposedLeaseId, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a for releasing a lease. - /// - /// The blob. - /// The attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A implementing the release lease operation. - /// - /// accessCondition - internal static RESTCommand ReleaseLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a for breaking a lease. - /// - /// The blob. - /// The attributes. - /// The amount of time to allow the lease to remain, rounded down to seconds. - /// If null, the break period is the remainder of the current lease, or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A implementing the break lease operation. - /// - internal static RESTCommand BreakLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options) - { - int? breakSeconds = null; - if (breakPeriod.HasValue) - { - CommonUtility.AssertInBounds("breakPeriod", breakPeriod.Value, TimeSpan.Zero, TimeSpan.MaxValue); - breakSeconds = (int)breakPeriod.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); - - int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); - if (!remainingLeaseTime.HasValue) - { - // Unexpected result from service. - throw new StorageException(cmd.CurrentResult, SR.LeaseTimeNotReceived, null /* inner */); - } - - return TimeSpan.FromSeconds(remainingLeaseTime.Value); - }; - - return putCmd; - } - - /// - /// Implementation of the StartCopyFromBlob method. Result is a BlobAttributes object derived from the response headers. - /// - /// The blob. - /// The attributes. - /// The URI of the source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that starts to copy the blob. - /// - /// sourceAccessCondition - internal static RESTCommand StartCopyFromBlobImpl(ICloudBlob blob, BlobAttributes attributes, Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options) - { - if (sourceAccessCondition != null && !string.IsNullOrEmpty(sourceAccessCondition.LeaseId)) - { - throw new ArgumentException(SR.LeaseConditionOnSource, "sourceAccessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.CopyFrom(uri, serverTimeout, source, sourceAccessCondition, destAccessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, attributes.Metadata); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex); - CopyState state = BlobHttpResponseParsers.GetCopyAttributes(resp); - attributes.Properties = BlobHttpResponseParsers.GetProperties(resp); - attributes.Metadata = BlobHttpResponseParsers.GetMetadata(resp); - attributes.CopyState = state; - return state.CopyId; - }; - - return putCmd; - } - - /// - /// Implementation of the AbortCopy method. No result is produced. - /// - /// The blob. - /// The attributes. - /// The copy ID of the copy operation to abort. - /// An object that represents the access conditions for the operation. If null, no condition is used. - /// An object that specifies additional options for the request. - /// - /// A that aborts the copy. - /// - internal static RESTCommand AbortCopyImpl(ICloudBlob blob, BlobAttributes attributes, string copyId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("copyId", copyId); - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.AbortCopy(uri, serverTimeout, copyId, accessCondition, ctx); - putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Updates this blob with the given attributes at the end of a fetch attributes operation. - /// - /// The new attributes. - /// The response. - /// if set to true, blob's MD5 will not be updated. - /// - internal static void UpdateAfterFetchAttributes(BlobAttributes attributes, HttpWebResponse response, bool ignoreMD5) - { - BlobProperties properties = BlobHttpResponseParsers.GetProperties(response); - - // If BlobType is specified and the value returned from cloud is different, - // then it's a client error and we need to throw. - if (attributes.Properties.BlobType != BlobType.Unspecified && attributes.Properties.BlobType != properties.BlobType) - { - throw new InvalidOperationException(SR.BlobTypeMismatch); - } - - if (ignoreMD5) - { - properties.ContentMD5 = attributes.Properties.ContentMD5; - } - - attributes.Properties = properties; - attributes.Metadata = BlobHttpResponseParsers.GetMetadata(response); - attributes.CopyState = BlobHttpResponseParsers.GetCopyAttributes(response); - } - - /// - /// Retrieve ETag, LMT, and Sequence-Number from response. - /// - /// The attributes. - /// The response to parse. - internal static void UpdateETagLMTAndSequenceNumber(BlobAttributes attributes, HttpWebResponse response) - { - BlobProperties parsedProperties = BlobHttpResponseParsers.GetProperties(response); - attributes.Properties.ETag = parsedProperties.ETag ?? attributes.Properties.ETag; - attributes.Properties.LastModified = parsedProperties.LastModified ?? attributes.Properties.LastModified; - attributes.Properties.PageBlobSequenceNumber = parsedProperties.PageBlobSequenceNumber ?? attributes.Properties.PageBlobSequenceNumber; - if (parsedProperties.Length > 0) - { - attributes.Properties.Length = parsedProperties.Length; - } - } - - /// - /// Converts the source blob of a copy operation to an appropriate access URI, taking Shared Access Signature credentials into account. - /// - /// The source blob. - /// A URI addressing the source blob, using SAS if appropriate. - internal static Uri SourceBlobToUri(ICloudBlob source) - { - CommonUtility.AssertNotNull("source", source); - return source.ServiceClient.Credentials.TransformUri(source.SnapshotQualifiedUri); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobStream.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobStream.cs deleted file mode 100644 index 0a1b53d63a2f1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlobStream.cs +++ /dev/null @@ -1,63 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.IO; - - /// - /// Represents a stream for writing to a blob. - /// - public abstract class CloudBlobStream : Stream - { -#if SYNC - /// - /// Clears all buffers for this stream, causes any buffered data to be written to the underlying blob, and commits the blob. - /// - public abstract void Commit(); -#endif - - /// - /// Begins an asynchronous commit operation. - /// - /// An optional asynchronous callback, to be called when the commit is complete. - /// A user-provided object that distinguishes this particular asynchronous commit request from other requests. - /// An ICancellableAsyncResult that represents the asynchronous commit, which could still be pending. - public abstract ICancellableAsyncResult BeginCommit(AsyncCallback callback, object state); - - /// - /// Waits for the pending asynchronous commit to complete. - /// - /// The reference to the pending asynchronous request to finish. - public abstract void EndCommit(IAsyncResult asyncResult); - - /// - /// Begins an asynchronous flush operation. - /// - /// An optional asynchronous callback, to be called when the flush is complete. - /// A user-provided object that distinguishes this particular asynchronous flush request from other requests. - /// An ICancellableAsyncResult that represents the asynchronous flush, which could still be pending. - public abstract ICancellableAsyncResult BeginFlush(AsyncCallback callback, object state); - - /// - /// Waits for the pending asynchronous flush to complete. - /// - /// The reference to the pending asynchronous request to finish. - public abstract void EndFlush(IAsyncResult asyncResult); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlockBlob.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlockBlob.cs deleted file mode 100644 index 2249d0083176a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudBlockBlob.cs +++ /dev/null @@ -1,4685 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Net; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a blob that is uploaded as a set of blocks. - /// - public sealed partial class CloudBlockBlob : ICloudBlob - { -#if SYNC - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - /// On the object returned by this method, the method must be called exactly once for every call. Failing to end a read process before beginning another read can cause unknown behavior. - [DoesServiceRequest] - public Stream OpenRead(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.FetchAttributes(accessCondition, options, operationContext); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - return new BlobReadStream(this, streamAccessCondition, modifiedOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenRead(AsyncCallback callback, object state) - { - return this.BeginOpenRead(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenRead(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - ICancellableAsyncResult result = this.BeginFetchAttributes( - accessCondition, - options, - operationContext, - ar => - { - try - { - this.EndFetchAttributes(ar); - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - storageAsyncResult.Result = new BlobReadStream(this, streamAccessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Ends an asynchronous operation to open a stream for reading from the blob. - /// - /// An that references the pending asynchronous operation. - /// A stream to be used for reading from the blob. - public Stream EndOpenRead(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - return storageAsyncResult.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync() - { - return this.OpenReadAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenRead, this.EndOpenRead, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.OpenReadAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenRead, this.EndOpenRead, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Opens a stream for writing to the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for writing to the blob. - public CloudBlobStream OpenWrite(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - - if ((accessCondition != null) && accessCondition.IsConditional) - { - try - { - this.FetchAttributes(accessCondition, options, operationContext); - } - catch (StorageException e) - { - if ((e.RequestInformation != null) && - (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) && - string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - // If we got a 404 and the condition was not an If-Match, - // we should continue with the operation. - } - else - { - throw; - } - } - } - - return new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); - } - -#endif - - /// - /// Begins an asynchronous operation to open a stream for writing to the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginOpenWrite(AsyncCallback callback, object state) - { - return this.BeginOpenWrite(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to open a stream for writing to the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginOpenWrite(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - - if ((accessCondition != null) && accessCondition.IsConditional) - { - ICancellableAsyncResult result = this.BeginFetchAttributes( - accessCondition, - options, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.EndFetchAttributes(ar); - } - catch (StorageException e) - { - if ((e.RequestInformation != null) && - (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) && - string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - // If we got a 404 and the condition was not an If-Match, - // we should continue with the operation. - } - else - { - storageAsyncResult.OnComplete(e); - return; - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - return; - } - - storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - }, - null /* state */); - - storageAsyncResult.CancelDelegate = result.Cancel; - } - else - { - storageAsyncResult.Result = new BlobWriteStream(this, accessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - } - - return storageAsyncResult; - } - - /// - /// Ends an asynchronous operation to open a stream for writing to the blob. - /// - /// An that references the pending asynchronous operation. - /// A stream to be used for writing to the blob. - public CloudBlobStream EndOpenWrite(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - return storageAsyncResult.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync() - { - return this.OpenWriteAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenWrite, this.EndOpenWrite, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.OpenWriteAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenWrite, this.EndOpenWrite, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromStream(Stream source, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.UploadFromStreamHelper(source, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromStream(Stream source, long length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.UploadFromStreamHelper(source, length, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - internal void UploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", length.Value, 1); - - if (source.CanSeek && length > source.Length - source.Position) - { - throw new ArgumentOutOfRangeException("length", SR.StreamLengthShortError); - } - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool lessThanSingleBlobThreshold = source.CanSeek - && (length ?? source.Length - source.Position) - <= this.ServiceClient.SingleBlobUploadThresholdInBytes; - if (this.ServiceClient.ParallelOperationThreadCount == 1 && lessThanSingleBlobThreshold) - { - string contentMD5 = null; - if (modifiedOptions.StoreBlobContentMD5.Value) - { - using (ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions)) - { - StreamDescriptor streamCopyState = new StreamDescriptor(); - long startPosition = source.Position; - source.WriteToSync(Stream.Null, length, null /* maxLength */, true, true, tempExecutionState, streamCopyState); - source.Position = startPosition; - contentMD5 = streamCopyState.Md5; - } - } - else - { - // Throw exception if we need to use Transactional MD5 but cannot store it - if (modifiedOptions.UseTransactionalMD5.Value) - { - throw new ArgumentException(SR.PutBlobNeedsStoreBlobContentMD5, "options"); - } - } - - Executor.ExecuteSync( - this.PutBlobImpl(source, length, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } - else - { - using (CloudBlobStream blobStream = this.OpenWrite(accessCondition, modifiedOptions, operationContext)) - { - using (ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions)) - { - source.WriteToSync(blobStream, length, null /* maxLength */, false, true, tempExecutionState, null /* streamCopyState */); - blobStream.Commit(); - } - } - } - } -#endif - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, null /* length */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, length, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, length, accessCondition, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - internal ICancellableAsyncResult BeginUploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("source", source); - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", length.Value, 1); - - if (source.CanSeek && length > source.Length - source.Position) - { - throw new ArgumentOutOfRangeException("length", SR.StreamLengthShortError); - } - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - bool lessThanSingleBlobThreshold = source.CanSeek && - (length ?? source.Length - source.Position) <= this.ServiceClient.SingleBlobUploadThresholdInBytes; - if (this.ServiceClient.ParallelOperationThreadCount == 1 && lessThanSingleBlobThreshold) - { - if (modifiedOptions.StoreBlobContentMD5.Value) - { - long startPosition = source.Position; - StreamDescriptor streamCopyState = new StreamDescriptor(); - source.WriteToAsync( - Stream.Null, - length, - null /* maxLength */, - true, - tempExecutionState, - streamCopyState, - completedState => - { - storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); - - try - { - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - if (completedState.ExceptionRef != null) - { - storageAsyncResult.OnComplete(completedState.ExceptionRef); - } - else - { - source.Position = startPosition; - this.UploadFromStreamHandler( - source, - length, - streamCopyState.Md5, - accessCondition, - operationContext, - modifiedOptions, - storageAsyncResult); - } - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }); - - // We do not need to do this inside a lock, as storageAsyncResult is - // not returned to the user yet. - storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; - } - else - { - if (modifiedOptions.UseTransactionalMD5.Value) - { - throw new ArgumentException(SR.PutBlobNeedsStoreBlobContentMD5, "options"); - } - - this.UploadFromStreamHandler( - source, - length, - null /* contentMD5 */, - accessCondition, - operationContext, - modifiedOptions, - storageAsyncResult); - } - } - else - { - ICancellableAsyncResult result = this.BeginOpenWrite( - accessCondition, - modifiedOptions, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - CloudBlobStream blobStream = this.EndOpenWrite(ar); - storageAsyncResult.OperationState = blobStream; - - source.WriteToAsync( - blobStream, - length, - null /* maxLength */, - false, - tempExecutionState, - null /* streamCopyState */, - completedState => - { - storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); - if (completedState.ExceptionRef != null) - { - storageAsyncResult.OnComplete(completedState.ExceptionRef); - } - else - { - try - { - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - ICancellableAsyncResult commitResult = blobStream.BeginCommit( - CloudBlobSharedImpl.BlobOutputStreamCommitCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = commitResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }); - - storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - // We do not need to do this inside a lock, as storageAsyncResult is - // not returned to the user yet. - storageAsyncResult.CancelDelegate = result.Cancel; - } - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private void UploadFromStreamHandler(Stream source, long? length, string contentMD5, AccessCondition accessCondition, OperationContext operationContext, BlobRequestOptions options, StorageAsyncResult storageAsyncResult) - { - ICancellableAsyncResult result = Executor.BeginExecuteAsync( - this.PutBlobImpl(source, length, contentMD5, accessCondition, options), - options.RetryPolicy, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - Executor.EndExecuteAsync(ar); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* asyncState */); - - storageAsyncResult.CancelDelegate = result.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - - /// - /// Ends an asynchronous operation to upload a stream to a block blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromStream(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source) - { - return this.UploadFromStreamAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsync(source, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, accessCondition, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length) - { - return this.UploadFromStreamAsync(source, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsync(source, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a file to the Blob service. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("path", path); - - using (FileStream fileStream = new FileStream(path, mode, FileAccess.Read)) - { - this.UploadFromStream(fileStream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AsyncCallback callback, object state) - { - return this.BeginUploadFromFile(path, mode, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("path", path); - - FileStream fileStream = new FileStream(path, mode, FileAccess.Read); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - OperationState = fileStream - }; - - try - { - ICancellableAsyncResult asyncResult = this.BeginUploadFromStream(fileStream, accessCondition, options, operationContext, this.UploadFromFileCallback, storageAsyncResult); - storageAsyncResult.CancelDelegate = asyncResult.Cancel; - return storageAsyncResult; - } - catch (Exception) - { - fileStream.Dispose(); - throw; - } - } - - /// - /// Called when the asynchronous UploadFromStream operation completes. - /// - /// The result of the asynchronous operation. - private void UploadFromFileCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - Exception exception = null; - - try - { - this.EndUploadFromStream(asyncResult); - } - catch (Exception e) - { - exception = e; - } - - // We should do FileStream disposal in a separate try-catch block - // because we want to close the file even if the operation fails. - try - { - FileStream fileStream = (FileStream)storageAsyncResult.OperationState; - fileStream.Dispose(); - } - catch (Exception e) - { - exception = e; - } - - storageAsyncResult.OnComplete(exception); - } - - /// - /// Ends an asynchronous operation to upload a file to a blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromFile(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode) - { - return this.UploadFromFileAsync(path, mode, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromFile, this.EndUploadFromFile, path, mode, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromFileAsync(path, mode, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromFile, this.EndUploadFromFile, path, mode, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("buffer", buffer); - - using (SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count)) - { - this.UploadFromStream(stream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AsyncCallback callback, object state) - { - return this.BeginUploadFromByteArray(buffer, index, count, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - - SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count); - return this.BeginUploadFromStream(stream, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromByteArray(IAsyncResult asyncResult) - { - this.EndUploadFromStream(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count) - { - return this.UploadFromByteArrayAsync(buffer, index, count, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromByteArray, this.EndUploadFromByteArray, buffer, index, count, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromByteArrayAsync(buffer, index, count, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromByteArray, this.EndUploadFromByteArray, buffer, index, count, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a string of text to a blob. - /// - /// The text to upload. - /// An object that indicates the text encoding to use. If null, UTF-8 will be used. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadText(string content, Encoding encoding = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("content", content); - - byte[] contentAsBytes = (encoding ?? Encoding.UTF8).GetBytes(content); - this.UploadFromByteArray(contentAsBytes, 0, contentAsBytes.Length, accessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadText(string content, AsyncCallback callback, object state) - { - return this.BeginUploadText(content, null /* encoding */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// An object that indicates the text encoding to use. If null, UTF-8 will be used. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadText(string content, Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("content", content); - - byte[] contentAsBytes = (encoding ?? Encoding.UTF8).GetBytes(content); - return this.BeginUploadFromByteArray(contentAsBytes, 0, contentAsBytes.Length, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to upload a string of text to a blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadText(IAsyncResult asyncResult) - { - this.EndUploadFromByteArray(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadTextAsync(string content) - { - return this.UploadTextAsync(content, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadTextAsync(string content, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadText, this.EndUploadText, content, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// An object that indicates the text encoding to use. If null, UTF-8 will be used. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadTextAsync(string content, Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadTextAsync(content, encoding, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a string of text to a blob. - /// - /// The text to upload. - /// An object that indicates the text encoding to use. If null, UTF-8 will be used. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadTextAsync(string content, Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadText, this.EndUploadText, content, encoding, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadToStream(Stream target, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.DownloadRangeToStream(target, null /* offset */, null /* length */, accessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToStream(Stream target, AsyncCallback callback, object state) - { - return this.BeginDownloadToStream(target, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToStream(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToStream(target, null /* offset */, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a stream. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadToStream(IAsyncResult asyncResult) - { - this.EndDownloadRangeToStream(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target) - { - return this.DownloadToStreamAsync(target, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToStream, this.EndDownloadToStream, target, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToStreamAsync(target, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToStream, this.EndDownloadToStream, target, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadToFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("path", path); - - using (FileStream fileStream = new FileStream(path, mode, FileAccess.Write)) - { - this.DownloadToStream(fileStream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AsyncCallback callback, object state) - { - return this.BeginDownloadToFile(path, mode, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("path", path); - - FileStream fileStream = new FileStream(path, mode, FileAccess.Write); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - OperationState = fileStream - }; - - try - { - ICancellableAsyncResult asyncResult = this.BeginDownloadToStream(fileStream, accessCondition, options, operationContext, this.DownloadToFileCallback, storageAsyncResult); - storageAsyncResult.CancelDelegate = asyncResult.Cancel; - return storageAsyncResult; - } - catch (Exception) - { - fileStream.Dispose(); - throw; - } - } - - /// - /// Called when the asynchronous DownloadToStream operation completes. - /// - /// The result of the asynchronous operation. - private void DownloadToFileCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - Exception exception = null; - - try - { - this.EndDownloadToStream(asyncResult); - } - catch (Exception e) - { - exception = e; - } - - // We should do FileStream disposal in a separate try-catch block - // because we want to close the file even if the operation fails. - try - { - FileStream fileStream = (FileStream)storageAsyncResult.OperationState; - fileStream.Dispose(); - } - catch (Exception e) - { - exception = e; - } - - storageAsyncResult.OnComplete(exception); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a file. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadToFile(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode) - { - return this.DownloadToFileAsync(path, mode, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToFile, this.EndDownloadToFile, path, mode, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToFileAsync(path, mode, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToFile, this.EndDownloadToFile, path, mode, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public int DownloadToByteArray(byte[] target, int index, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - return this.DownloadRangeToByteArray(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext); - } - -#endif - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AsyncCallback callback, object state) - { - return this.BeginDownloadToByteArray(target, index, null /* accessCondition */, null /* options */, null /*operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToByteArray(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - public int EndDownloadToByteArray(IAsyncResult asyncResult) - { - return this.EndDownloadRangeToByteArray(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index) - { - return this.DownloadToByteArrayAsync(target, index, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadToByteArray, this.EndDownloadToByteArray, target, index, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToByteArrayAsync(target, index, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadToByteArray, this.EndDownloadToByteArray, target, index, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the blob's contents as a string. - /// - /// An object that indicates the text encoding to use. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The contents of the blob, as a string. - public string DownloadText(Encoding encoding = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (SyncMemoryStream stream = new SyncMemoryStream()) - { - this.DownloadToStream(stream, accessCondition, options, operationContext); - byte[] streamAsBytes = stream.GetBuffer(); - return (encoding ?? Encoding.UTF8).GetString(streamAsBytes, 0, (int)stream.Length); - } - } -#endif - - /// - /// Begins an asynchronous operation to download the blob's contents as a string. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginDownloadText(AsyncCallback callback, object state) - { - return this.BeginDownloadText(null /* encoding */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the blob's contents as a string. - /// - /// An object that indicates the text encoding to use. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginDownloadText(Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - SyncMemoryStream stream = new SyncMemoryStream(); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) { OperationState = Tuple.Create(stream, encoding) }; - - ICancellableAsyncResult result = this.BeginDownloadToStream( - stream, - accessCondition, - options, - operationContext, - this.DownloadTextCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Called when the asynchronous DownloadToStream operation completes. - /// - /// The result of the asynchronous operation. - private void DownloadTextCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - - try - { - this.EndDownloadToStream(asyncResult); - - Tuple state = (Tuple)storageAsyncResult.OperationState; - byte[] streamAsBytes = state.Item1.GetBuffer(); - storageAsyncResult.Result = (state.Item2 ?? Encoding.UTF8).GetString(streamAsBytes, 0, (int)state.Item1.Length); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Ends an asynchronous operation to download the blob's contents as a string. - /// - /// An that references the pending asynchronous operation. - /// The contents of the blob, as a string. - public string EndDownloadText(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the blob's contents as a string. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadTextAsync() - { - return this.DownloadTextAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the blob's contents as a string. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadTextAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadText, this.EndDownloadText, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the blob's contents as a string. - /// - /// An object that indicates the text encoding to use. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadTextAsync(Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadTextAsync(encoding, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the blob's contents as a string. - /// - /// An object that indicates the text encoding to use. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadTextAsync(Encoding encoding, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadText, this.EndDownloadText, encoding, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target, offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToStream(target, offset, length, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target, offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadRangeToStream(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length) - { - return this.DownloadRangeToStreamAsync(target, offset, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadRangeToStream, this.EndDownloadRangeToStream, target, offset, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToStreamAsync(target, offset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadRangeToStream, this.EndDownloadRangeToStream, target, offset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public int DownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (SyncMemoryStream stream = new SyncMemoryStream(target, index)) - { - this.DownloadRangeToStream(stream, blobOffset, length, accessCondition, options, operationContext); - return (int)stream.Position; - } - } -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToByteArray(target, index, blobOffset, length, null /* accesCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - SyncMemoryStream stream = new SyncMemoryStream(target, index); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) { OperationState = stream }; - - ICancellableAsyncResult result = this.BeginDownloadRangeToStream( - stream, - blobOffset, - length, - accessCondition, - options, - operationContext, - this.DownloadRangeToByteArrayCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Called when the asynchronous DownloadRangeToStream operation completes. - /// - /// The result of the asynchronous operation. - private void DownloadRangeToByteArrayCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - - try - { - this.EndDownloadRangeToStream(asyncResult); - - SyncMemoryStream stream = (SyncMemoryStream)storageAsyncResult.OperationState; - storageAsyncResult.Result = (int)stream.Position; - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - public int EndDownloadRangeToByteArray(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadRangeToByteArray, this.EndDownloadRangeToByteArray, target, index, blobOffset, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadRangeToByteArray, this.EndDownloadRangeToByteArray, target, index, blobOffset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Checks existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - [DoesServiceRequest] - public bool Exists(BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(AsyncCallback callback, object state) - { - return this.BeginExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to check existence of the blob. - /// - /// An that references the pending asynchronous operation. - /// true if the blob exists. - public bool EndExists(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync() - { - return this.ExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.ExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void FetchAttributes(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AsyncCallback callback, object state) - { - return this.BeginFetchAttributes(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to populate the blob's properties and metadata. - /// - /// An that references the pending asynchronous operation. - public void EndFetchAttributes(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync() - { - return this.FetchAttributesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.FetchAttributesAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetMetadata(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AsyncCallback callback, object state) - { - return this.BeginSetMetadata(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to update the blob's metadata. - /// - /// An that references the pending asynchronous operation. - public void EndSetMetadata(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync() - { - return this.SetMetadataAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetMetadataAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetProperties(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetProperties(AsyncCallback callback, object state) - { - return this.BeginSetProperties(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetProperties(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to update the blob's properties. - /// - /// An that references the pending asynchronous operation. - public void EndSetProperties(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync() - { - return this.SetPropertiesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetProperties, this.EndSetProperties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetPropertiesAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetProperties, this.EndSetProperties, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void Delete(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state) - { - return this.BeginDelete(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to delete the blob. - /// - /// An that references the pending asynchronous operation. - public void EndDelete(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync() - { - return this.DeleteAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteAsync(deleteSnapshotsOption, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, deleteSnapshotsOption, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob did already exist and was deleted; otherwise false. - [DoesServiceRequest] - public bool DeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - if (!exists) - { - return false; - } - - try - { - this.Delete(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } -#endif - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state) - { - return this.BeginDeleteIfExists(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - this.DeleteIfExistsHandler(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult savedExistsResult = this.BeginExists( - options, - operationContext, - existsResult => - { - storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - bool exists = this.EndExists(existsResult); - if (!exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - return; - } - - ICancellableAsyncResult savedDeleteResult = this.BeginDelete( - deleteSnapshotsOption, - accessCondition, - options, - operationContext, - deleteResult => - { - storageAsyncResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously); - storageAsyncResult.CancelDelegate = null; - try - { - this.EndDelete(deleteResult); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedDeleteResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Returns the result of an asynchronous request to delete the blob if it already exists. - /// - /// An that references the pending asynchronous operation. - /// true if the blob did already exist and was deleted; otherwise, false. - public bool EndDeleteIfExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteIfExistsAsync(deleteSnapshotsOption, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, deleteSnapshotsOption, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Creates a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// A blob snapshot. - [DoesServiceRequest] - public CloudBlockBlob CreateSnapshot(IDictionary metadata = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to create a snapshot of the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateSnapshot(AsyncCallback callback, object state) - { - return this.BeginCreateSnapshot(null /* metadata */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateSnapshot(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to create a snapshot of the blob. - /// - /// An that references the pending asynchronous operation. - /// A blob snapshot. - public CloudBlockBlob EndCreateSnapshot(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync() - { - return this.CreateSnapshotAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateSnapshot, this.EndCreateSnapshot, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateSnapshotAsync(metadata, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateSnapshot, this.EndCreateSnapshot, metadata, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public string AcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AsyncCallback callback, object state) - { - return this.BeginAcquireLease(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to acquire a lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The ID of the acquired lease. - public string EndAcquireLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void RenewLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginRenewLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to renew a lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - public void EndRenewLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.RenewLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public string ChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginChangeLease(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to change the lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The new lease ID. - public string EndChangeLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void ReleaseLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginReleaseLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to release the lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - public void EndReleaseLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ReleaseLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public TimeSpan BreakLease(TimeSpan? breakPeriod = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AsyncCallback callback, object state) - { - return this.BeginBreakLease(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to break the current lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// A representing the amount of time before the lease ends, to the second. - public TimeSpan EndBreakLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.BreakLeaseAsync(breakPeriod, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void PutBlock(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("blockData", blockData); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - - Stream seekableStream = blockData; - if (!blockData.CanSeek || requiresContentMD5) - { - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - Stream writeToStream; - if (blockData.CanSeek) - { - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - long startPosition = seekableStream.Position; - StreamDescriptor streamCopyState = new StreamDescriptor(); - blockData.WriteToSync(writeToStream, null /* copyLength */, Constants.MaxBlockSize, requiresContentMD5, true, tempExecutionState, streamCopyState); - seekableStream.Position = startPosition; - - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - } - - Executor.ExecuteSync( - this.PutBlockImpl(seekableStream, blockId, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPutBlock(string blockId, Stream blockData, string contentMD5, AsyncCallback callback, object state) - { - return this.BeginPutBlock(blockId, blockData, contentMD5, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginPutBlock(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("blockData", blockData); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - if (blockData.CanSeek && !requiresContentMD5) - { - this.PutBlockHandler(blockId, blockData, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - } - else - { - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; - - Stream seekableStream; - Stream writeToStream; - if (blockData.CanSeek) - { - seekableStream = blockData; - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - long startPosition = seekableStream.Position; - StreamDescriptor streamCopyState = new StreamDescriptor(); - blockData.WriteToAsync( - writeToStream, - null /* copyLength */, - Constants.MaxBlockSize, - requiresContentMD5, - tempExecutionState, - streamCopyState, - completedState => - { - storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); - - if (completedState.ExceptionRef != null) - { - storageAsyncResult.OnComplete(completedState.ExceptionRef); - } - else - { - try - { - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - - seekableStream.Position = startPosition; - this.PutBlockHandler(blockId, seekableStream, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }); - } - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private void PutBlockHandler(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult result = Executor.BeginExecuteAsync( - this.PutBlockImpl(blockData, blockId, contentMD5, accessCondition, options), - options.RetryPolicy, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - Executor.EndExecuteAsync(ar); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* asyncState */); - - storageAsyncResult.CancelDelegate = result.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Ends an asynchronous operation to upload a single block. - /// - /// An that references the pending asynchronous operation. - public void EndPutBlock(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockAsync(string blockId, Stream blockData, string contentMD5) - { - return this.PutBlockAsync(blockId, blockData, contentMD5, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockAsync(string blockId, Stream blockData, string contentMD5, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginPutBlock, this.EndPutBlock, blockId, blockData, contentMD5, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockAsync(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.PutBlockAsync(blockId, blockData, contentMD5, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockAsync(string blockId, Stream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginPutBlock, this.EndPutBlock, blockId, blockData, contentMD5, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void PutBlockList(IEnumerable blockList, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - IEnumerable items = blockList.Select(i => new PutBlockListItem(i, BlockSearchMode.Latest)); - Executor.ExecuteSync( - this.PutBlockListImpl(items, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPutBlockList(IEnumerable blockList, AsyncCallback callback, object state) - { - return this.BeginPutBlockList(blockList, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPutBlockList(IEnumerable blockList, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - IEnumerable items = blockList.Select(i => new PutBlockListItem(i, BlockSearchMode.Latest)); - return Executor.BeginExecuteAsync( - this.PutBlockListImpl(items, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An that references the pending asynchronous operation. - public void EndPutBlockList(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockListAsync(IEnumerable blockList) - { - return this.PutBlockListAsync(blockList, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockListAsync(IEnumerable blockList, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginPutBlockList, this.EndPutBlockList, blockList, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockListAsync(IEnumerable blockList, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.PutBlockListAsync(blockList, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PutBlockListAsync(IEnumerable blockList, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginPutBlockList, this.EndPutBlockList, blockList, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Returns an enumerable collection of the blob's blocks, using the specified block list filter. - /// - /// One of the enumeration values that indicates whether to return - /// committed blocks, uncommitted blocks, or both. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of objects implementing . - [DoesServiceRequest] - public IEnumerable DownloadBlockList(BlockListingFilter blockListingFilter = BlockListingFilter.Committed, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - this.GetBlockListImpl(blockListingFilter, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadBlockList(AsyncCallback callback, object state) - { - return this.BeginDownloadBlockList(BlockListingFilter.Committed, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// One of the enumeration values that indicates whether to return - /// committed blocks, uncommitted blocks, or both. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadBlockList(BlockListingFilter blockListingFilter, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.GetBlockListImpl(blockListingFilter, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// An that references the pending asynchronous operation. - /// An enumerable collection of objects implementing . - public IEnumerable EndDownloadBlockList(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> DownloadBlockListAsync() - { - return this.DownloadBlockListAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> DownloadBlockListAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadBlockList, this.EndDownloadBlockList, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// One of the enumeration values that indicates whether to return - /// committed blocks, uncommitted blocks, or both. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> DownloadBlockListAsync(BlockListingFilter blockListingFilter, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadBlockListAsync(blockListingFilter, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return an enumerable collection of the blob's blocks, - /// using the specified block list filter. - /// - /// One of the enumeration values that indicates whether to return - /// committed blocks, uncommitted blocks, or both. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> DownloadBlockListAsync(BlockListingFilter blockListingFilter, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadBlockList, this.EndDownloadBlockList, blockListingFilter, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public string StartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition = null, AccessCondition destAccessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public string StartCopyFromBlob(CloudBlockBlob source, AccessCondition sourceAccessCondition = null, AccessCondition destAccessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - return this.StartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext); - } - -#endif - /// - /// Begins an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(source, null /* sourceAccessCondition */, null /* destAccessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The source blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(CloudBlockBlob source, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), callback, state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(CloudBlockBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// An that references the pending asynchronous operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - public string EndStartCopyFromBlob(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source) - { - return this.StartCopyFromBlobAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudBlockBlob source) - { - return this.StartCopyFromBlobAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudBlockBlob source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(source, sourceAccessCondition, destAccessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, sourceAccessCondition, destAccessCondition, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudBlockBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(source, sourceAccessCondition, destAccessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudBlockBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, sourceAccessCondition, destAccessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void AbortCopy(string copyId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAbortCopy(string copyId, AsyncCallback callback, object state) - { - return this.BeginAbortCopy(copyId, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAbortCopy(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to abort an ongoing blob copy operation. - /// - /// An that references the pending asynchronous operation. - public void EndAbortCopy(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId) - { - return this.AbortCopyAsync(copyId, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAbortCopy, this.EndAbortCopy, copyId, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.AbortCopyAsync(copyId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAbortCopy, this.EndAbortCopy, copyId, accessCondition, options, operationContext, cancellationToken); - } -#endif - - /// - /// Implementation for the CreateSnapshot method. - /// - /// A collection of name-value pairs defining the metadata of the snapshot, or null. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the snapshot. - /// If the metadata parameter is null then no metadata is associated with the request. - internal RESTCommand CreateSnapshotImpl(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Snapshot(uri, serverTimeout, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => - { - if (metadata != null) - { - BlobHttpWebRequestFactory.AddMetadata(r, metadata); - } - }; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp)); - CloudBlockBlob snapshot = new CloudBlockBlob(this.Name, snapshotTime, this.Container); - snapshot.attributes.Metadata = new Dictionary(metadata ?? this.Metadata); - snapshot.attributes.Properties = new BlobProperties(this.Properties); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(snapshot.attributes, resp); - return snapshot; - }; - - return putCmd; - } - - /// - /// Uploads the full blob from a seekable stream. - /// - /// The content stream. Must be seekable. - /// Number of bytes to upload from the content stream starting at its current position. - /// The content MD5. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the stream. - private RESTCommand PutBlobImpl(Stream stream, long? length, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - long offset = stream.Position; - this.Properties.ContentMD5 = contentMD5; - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.SendStream = stream; - putCmd.SendStreamLength = length ?? stream.Length - offset; - putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, offset); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Put(uri, serverTimeout, this.Properties, BlobType.BlockBlob, 0, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - this.Properties.Length = putCmd.SendStreamLength.Value; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Uploads the block. - /// - /// The source stream. - /// The block ID. - /// The content MD5. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that uploads the block. - internal RESTCommand PutBlockImpl(Stream source, string blockId, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - long offset = source.Position; - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.SendStream = source; - putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, offset); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutBlock(uri, serverTimeout, blockId, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => - { - if (!string.IsNullOrEmpty(contentMD5)) - { - r.Headers[HttpRequestHeader.ContentMd5] = contentMD5; - } - }; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Uploads the block list. - /// - /// The blocks to upload. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that uploads the block list. - internal RESTCommand PutBlockListImpl(IEnumerable blocks, AccessCondition accessCondition, BlobRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - BlobRequest.WriteBlockListBody(blocks, memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); -#if !WINDOWS_PHONE - string contentMD5 = memoryStream.ComputeMD5Hash(); - memoryStream.Seek(0, SeekOrigin.Begin); -#endif - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutBlockList(uri, serverTimeout, this.Properties, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => - { -#if !WINDOWS_PHONE - r.Headers[HttpRequestHeader.ContentMd5] = contentMD5; -#endif - BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); - }; - putCmd.SendStream = memoryStream; - putCmd.RecoveryAction = RecoveryActions.RewindStream; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - this.Properties.Length = -1; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Gets the download block list. - /// - /// The types of blocks. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the download block list. - internal RESTCommand> GetBlockListImpl(BlockListingFilter typesOfBlocks, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetBlockList(uri, serverTimeout, this.SnapshotTime, typesOfBlocks, accessCondition, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - GetBlockListResponse responseParser = new GetBlockListResponse(cmd.ResponseStream); - IEnumerable blocks = new List(responseParser.Blocks); - return blocks; - }; - - return getCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudPageBlob.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudPageBlob.cs deleted file mode 100644 index feb7190c3a06c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/CloudPageBlob.cs +++ /dev/null @@ -1,4753 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a Windows Azure page blob. - /// - public sealed partial class CloudPageBlob : ICloudBlob - { -#if SYNC - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - /// On the object returned by this method, the method must be called exactly once for every call. Failing to end a read process before beginning another read can cause unknown behavior. - [DoesServiceRequest] - public Stream OpenRead(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.FetchAttributes(accessCondition, options, operationContext); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - return new BlobReadStream(this, streamAccessCondition, modifiedOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenRead(AsyncCallback callback, object state) - { - return this.BeginOpenRead(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenRead(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - ICancellableAsyncResult result = this.BeginFetchAttributes( - accessCondition, - options, - operationContext, - ar => - { - try - { - this.EndFetchAttributes(ar); - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - storageAsyncResult.Result = new BlobReadStream(this, streamAccessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Ends an asynchronous operation to open a stream for reading from the blob. - /// - /// An that references the pending asynchronous operation. - /// A stream to be used for reading from the blob. - public Stream EndOpenRead(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - return storageAsyncResult.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync() - { - return this.OpenReadAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenRead, this.EndOpenRead, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.OpenReadAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenRead, this.EndOpenRead, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Opens a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for writing to the blob. - [DoesServiceRequest] - public CloudBlobStream OpenWrite(long? size, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - bool createNew = size.HasValue; - - if (createNew) - { - this.Create(size.Value, accessCondition, options, operationContext); - } - else - { - if (modifiedOptions.StoreBlobContentMD5.Value) - { - throw new ArgumentException(SR.MD5NotPossible); - } - - this.FetchAttributes(accessCondition, options, operationContext); - size = this.Properties.Length; - } - - if (accessCondition != null) - { - accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); - } - - return new BlobWriteStream(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenWrite(long? size, AsyncCallback callback, object state) - { - return this.BeginOpenWrite(size, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginOpenWrite(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - bool createNew = size.HasValue; - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - ICancellableAsyncResult result; - if (createNew) - { - result = this.BeginCreate( - size.Value, - accessCondition, - options, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.EndCreate(ar); - - if (accessCondition != null) - { - accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); - } - - storageAsyncResult.Result = new BlobWriteStream(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - } - else - { - if (modifiedOptions.StoreBlobContentMD5.Value) - { - throw new ArgumentException(SR.MD5NotPossible); - } - - result = this.BeginFetchAttributes( - accessCondition, - options, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - this.EndFetchAttributes(ar); - - if (accessCondition != null) - { - accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); - } - - storageAsyncResult.Result = new BlobWriteStream(this, this.Properties.Length, createNew, accessCondition, modifiedOptions, operationContext); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - } - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Ends an asynchronous operation to open a stream for writing to the blob. - /// - /// An that references the pending asynchronous operation. - /// A stream to be used for writing to the blob. - public CloudBlobStream EndOpenWrite(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - return storageAsyncResult.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(long? size) - { - return this.OpenWriteAsync(size, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(long? size, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenWrite, this.EndOpenWrite, size, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.OpenWriteAsync(size, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to open a stream for writing to the blob. - /// - /// The size of the page blob, in bytes. The size must be a multiple of 512. If null, the page blob must already exist. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task OpenWriteAsync(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginOpenWrite, this.EndOpenWrite, size, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadToStream(Stream target, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.DownloadRangeToStream(target, null /* offset */, null /* length */, accessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToStream(Stream target, AsyncCallback callback, object state) - { - return this.BeginDownloadToStream(target, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToStream(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToStream(target, null /* offset */, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a stream. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadToStream(IAsyncResult asyncResult) - { - this.EndDownloadRangeToStream(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target) - { - return this.DownloadToStreamAsync(target, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToStream, this.EndDownloadToStream, target, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToStreamAsync(target, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToStream, this.EndDownloadToStream, target, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadToFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("path", path); - - using (FileStream fileStream = new FileStream(path, mode, FileAccess.Write)) - { - this.DownloadToStream(fileStream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AsyncCallback callback, object state) - { - return this.BeginDownloadToFile(path, mode, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("path", path); - - FileStream fileStream = new FileStream(path, mode, FileAccess.Write); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - OperationState = fileStream - }; - - try - { - ICancellableAsyncResult asyncResult = this.BeginDownloadToStream(fileStream, accessCondition, options, operationContext, this.DownloadToFileCallback, storageAsyncResult); - storageAsyncResult.CancelDelegate = asyncResult.Cancel; - return storageAsyncResult; - } - catch (Exception) - { - fileStream.Dispose(); - throw; - } - } - - /// - /// Called when the asynchronous DownloadToStream operation completes. - /// - /// The result of the asynchronous operation. - private void DownloadToFileCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - Exception exception = null; - - try - { - this.EndDownloadToStream(asyncResult); - } - catch (Exception e) - { - exception = e; - } - - // We should do FileStream disposal in a separate try-catch block - // because we want to close the file even if the operation fails. - try - { - FileStream fileStream = (FileStream)storageAsyncResult.OperationState; - fileStream.Dispose(); - } - catch (Exception e) - { - exception = e; - } - - storageAsyncResult.OnComplete(exception); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a file. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadToFile(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode) - { - return this.DownloadToFileAsync(path, mode, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToFile, this.EndDownloadToFile, path, mode, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToFileAsync(path, mode, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadToFile, this.EndDownloadToFile, path, mode, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public int DownloadToByteArray(byte[] target, int index, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - return this.DownloadRangeToByteArray(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AsyncCallback callback, object state) - { - return this.BeginDownloadToByteArray(target, index, null /* accessCondition */, null /* options */, null /*operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToByteArray(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to download the contents of a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - public int EndDownloadToByteArray(IAsyncResult asyncResult) - { - return this.EndDownloadRangeToByteArray(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index) - { - return this.DownloadToByteArrayAsync(target, index, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadToByteArray, this.EndDownloadToByteArray, target, index, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadToByteArrayAsync(target, index, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadToByteArray, this.EndDownloadToByteArray, target, index, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void DownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target, offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToStream(target, offset, length, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target, offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// An that references the pending asynchronous operation. - public void EndDownloadRangeToStream(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length) - { - return this.DownloadRangeToStreamAsync(target, offset, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadRangeToStream, this.EndDownloadRangeToStream, target, offset, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToStreamAsync(target, offset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDownloadRangeToStream, this.EndDownloadRangeToStream, target, offset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public int DownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (SyncMemoryStream stream = new SyncMemoryStream(target, index)) - { - this.DownloadRangeToStream(stream, blobOffset, length, accessCondition, options, operationContext); - return (int)stream.Position; - } - } -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AsyncCallback callback, object state) - { - return this.BeginDownloadRangeToByteArray(target, index, blobOffset, length, null /* accesCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - SyncMemoryStream stream = new SyncMemoryStream(target, index); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) { OperationState = stream }; - - ICancellableAsyncResult result = this.BeginDownloadRangeToStream( - stream, - blobOffset, - length, - accessCondition, - options, - operationContext, - this.DownloadRangeToByteArrayCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = result.Cancel; - return storageAsyncResult; - } - - /// - /// Called when the asynchronous DownloadRangeToStream operation completes. - /// - /// The result of the asynchronous operation. - private void DownloadRangeToByteArrayCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - - try - { - this.EndDownloadRangeToStream(asyncResult); - - SyncMemoryStream stream = (SyncMemoryStream)storageAsyncResult.OperationState; - storageAsyncResult.Result = (int)stream.Position; - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - public int EndDownloadRangeToByteArray(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadRangeToByteArray, this.EndDownloadRangeToByteArray, target, index, blobOffset, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDownloadRangeToByteArray, this.EndDownloadRangeToByteArray, target, index, blobOffset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromStream(Stream source, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.UploadFromStreamHelper(source, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromStream(Stream source, long length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.UploadFromStreamHelper(source, length, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - internal void UploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - if (!source.CanSeek) - { - throw new InvalidOperationException(); - } - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", length.Value, 1, source.Length - source.Position); - } - else - { - length = source.Length - source.Position; - } - - if ((length % Constants.PageSize) != 0) - { - throw new ArgumentException(SR.InvalidPageSize, "source"); - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - using (CloudBlobStream blobStream = this.OpenWrite(length, accessCondition, modifiedOptions, operationContext)) - { - using (ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions)) - { - source.WriteToSync(blobStream, length, null /* maxLength */, false, true, tempExecutionState, null /* streamCopyState */); - blobStream.Commit(); - } - } - } -#endif - - /// - /// Begins an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, null /* length */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, null /* length */, accessCondition, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// Specifies the number of bytes from the Stream source to upload from the start position. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, length, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// Specifies the number of bytes from the Stream source to upload from the start position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginUploadFromStreamHelper(source, length, accessCondition, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// Specifies the number of bytes from the Stream source to upload from the start position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - internal ICancellableAsyncResult BeginUploadFromStreamHelper(Stream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("source", source); - - if (!source.CanSeek) - { - throw new InvalidOperationException(); - } - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", (long)length, 1, source.Length - source.Position); - } - else - { - length = source.Length - source.Position; - } - - if ((length % Constants.PageSize) != 0) - { - throw new ArgumentException(SR.InvalidPageSize, "source"); - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - ICancellableAsyncResult result = this.BeginOpenWrite( - length, - accessCondition, - modifiedOptions, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - CloudBlobStream blobStream = this.EndOpenWrite(ar); - storageAsyncResult.OperationState = blobStream; - - source.WriteToAsync( - blobStream, - length, - null /* maxLength */, - false, - tempExecutionState, - null /* streamCopyState */, - completedState => - { - storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); - if (completedState.ExceptionRef != null) - { - storageAsyncResult.OnComplete(completedState.ExceptionRef); - } - else - { - try - { - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - ICancellableAsyncResult commitResult = blobStream.BeginCommit( - CloudBlobSharedImpl.BlobOutputStreamCommitCallback, - storageAsyncResult); - - storageAsyncResult.CancelDelegate = commitResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }); - - storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - // We do not need to do this inside a lock, as storageAsyncResult is - // not returned to the user yet. - storageAsyncResult.CancelDelegate = result.Cancel; - - return storageAsyncResult; - } - - /// - /// Ends an asynchronous operation to upload a stream to a page blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromStream(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source) - { - return this.UploadFromStreamAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsync(source, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, accessCondition, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length) - { - return this.UploadFromStreamAsync(source, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsync(source, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromStream, this.EndUploadFromStream, source, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads a file to the Windows Azure Blob Service. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("path", path); - - using (FileStream fileStream = new FileStream(path, mode, FileAccess.Read)) - { - this.UploadFromStream(fileStream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AsyncCallback callback, object state) - { - return this.BeginUploadFromFile(path, mode, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("path", path); - - FileStream fileStream = new FileStream(path, mode, FileAccess.Read); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - OperationState = fileStream - }; - - try - { - ICancellableAsyncResult asyncResult = this.BeginUploadFromStream(fileStream, accessCondition, options, operationContext, this.UploadFromFileCallback, storageAsyncResult); - storageAsyncResult.CancelDelegate = asyncResult.Cancel; - return storageAsyncResult; - } - catch (Exception) - { - fileStream.Dispose(); - throw; - } - } - - /// - /// Called when the asynchronous UploadFromStream operation completes. - /// - /// The result of the asynchronous operation. - private void UploadFromFileCallback(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult.AsyncState; - Exception exception = null; - - try - { - this.EndUploadFromStream(asyncResult); - } - catch (Exception e) - { - exception = e; - } - - // We should do FileStream disposal in a separate try-catch block - // because we want to close the file even if the operation fails. - try - { - FileStream fileStream = (FileStream)storageAsyncResult.OperationState; - fileStream.Dispose(); - } - catch (Exception e) - { - exception = e; - } - - storageAsyncResult.OnComplete(exception); - } - - /// - /// Ends an asynchronous operation to upload a file to a blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromFile(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode) - { - return this.UploadFromFileAsync(path, mode, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromFile, this.EndUploadFromFile, path, mode, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromFileAsync(path, mode, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromFile, this.EndUploadFromFile, path, mode, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("buffer", buffer); - - using (SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count)) - { - this.UploadFromStream(stream, accessCondition, options, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AsyncCallback callback, object state) - { - return this.BeginUploadFromByteArray(buffer, index, count, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("buffer", buffer); - - SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count); - return this.BeginUploadFromStream(stream, accessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An that references the pending asynchronous operation. - public void EndUploadFromByteArray(IAsyncResult asyncResult) - { - this.EndUploadFromStream(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count) - { - return this.UploadFromByteArrayAsync(buffer, index, count, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromByteArray, this.EndUploadFromByteArray, buffer, index, count, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromByteArrayAsync(buffer, index, count, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUploadFromByteArray, this.EndUploadFromByteArray, buffer, index, count, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Creates a page blob. - /// - /// The maximum size of the page blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void Create(long size, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - this.CreateImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to create a page blob. - /// - /// The maximum size of the page blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(long size, AsyncCallback callback, object state) - { - return this.BeginCreate(size, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a page blob. - /// - /// The maximum size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.CreateImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to create a page blob. - /// - /// An that references the pending asynchronous operation. - public void EndCreate(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a page blob. - /// - /// The maximum size of the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(long size) - { - return this.CreateAsync(size, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a page blob. - /// - /// The maximum size of the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(long size, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, size, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a page blob. - /// - /// The maximum size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateAsync(size, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a page blob. - /// - /// The maximum size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, size, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Resizes the page blob to the specified size. - /// - /// The size of the page blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void Resize(long size, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - this.ResizeImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the page blob, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginResize(long size, AsyncCallback callback, object state) - { - return this.BeginResize(size, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginResize(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ResizeImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to resize the page blob. - /// - /// An that references the pending asynchronous operation. - public void EndResize(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the blob, in bytes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ResizeAsync(long size) - { - return this.ResizeAsync(size, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the blob, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ResizeAsync(long size, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginResize, this.EndResize, size, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ResizeAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ResizeAsync(size, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to resize the page blob to the specified size. - /// - /// The size of the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ResizeAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginResize, this.EndResize, size, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetSequenceNumber(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - this.SetSequenceNumberImpl(sequenceNumberAction, sequenceNumber, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetSequenceNumber(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AsyncCallback callback, object state) - { - return this.BeginSetSequenceNumber(sequenceNumberAction, sequenceNumber, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetSequenceNumber(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.SetSequenceNumberImpl(sequenceNumberAction, sequenceNumber, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to set the page blob's sequence number. - /// - /// An that references the pending asynchronous operation. - public void EndSetSequenceNumber(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber) - { - return this.SetSequenceNumberAsync(sequenceNumberAction, sequenceNumber, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetSequenceNumber, this.EndSetSequenceNumber, sequenceNumberAction, sequenceNumber, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetSequenceNumberAsync(sequenceNumberAction, sequenceNumber, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetSequenceNumber, this.EndSetSequenceNumber, sequenceNumberAction, sequenceNumber, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Checks existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - [DoesServiceRequest] - public bool Exists(BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(AsyncCallback callback, object state) - { - return this.BeginExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to check existence of the blob. - /// - /// An that references the pending asynchronous operation. - /// true if the blob exists. - public bool EndExists(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync() - { - return this.ExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.ExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void FetchAttributes(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AsyncCallback callback, object state) - { - return this.BeginFetchAttributes(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to populate the blob's properties and metadata. - /// - /// An that references the pending asynchronous operation. - public void EndFetchAttributes(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync() - { - return this.FetchAttributesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.FetchAttributesAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets a collection of valid page ranges and their starting and ending bytes. - /// - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of page ranges. - [DoesServiceRequest] - public IEnumerable GetPageRanges(long? offset = null, long? length = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - this.GetPageRangesImpl(offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to return a collection of valid page ranges and their starting and ending bytes. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPageRanges(AsyncCallback callback, object state) - { - return this.BeginGetPageRanges(null /* offset */, null /* length */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a collection of valid page ranges and their starting and ending bytes. - /// - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPageRanges(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.GetPageRangesImpl(offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return a collection of valid page ranges and their starting and ending bytes. - /// - /// An that references the pending asynchronous operation. - /// An enumerable collection of page ranges. - public IEnumerable EndGetPageRanges(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return a collection of page ranges and their starting and ending bytes. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetPageRangesAsync() - { - return this.GetPageRangesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a collection of page ranges and their starting and ending bytes. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetPageRangesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPageRanges, this.EndGetPageRanges, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a collection of page ranges and their starting and ending bytes. - /// - /// The starting offset of the data range, in bytes. Must be a multiple of 512. - /// The length of the data range, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetPageRangesAsync(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.GetPageRangesAsync(offset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a collection of page ranges and their starting and ending bytes. - /// - /// The starting offset of the data range, in bytes. Must be a multiple of 512. - /// The length of the data range, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetPageRangesAsync(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPageRanges, this.EndGetPageRanges, offset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetMetadata(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AsyncCallback callback, object state) - { - return this.BeginSetMetadata(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to update the blob's metadata. - /// - /// An that references the pending asynchronous operation. - public void EndSetMetadata(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync() - { - return this.SetMetadataAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetMetadataAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void SetProperties(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetProperties(AsyncCallback callback, object state) - { - return this.BeginSetProperties(null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetProperties(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to update the blob's properties. - /// - /// An that references the pending asynchronous operation. - public void EndSetProperties(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync() - { - return this.SetPropertiesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetProperties, this.EndSetProperties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.SetPropertiesAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetProperties, this.EndSetProperties, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void Delete(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state) - { - return this.BeginDelete(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to delete the blob. - /// - /// An that references the pending asynchronous operation. - public void EndDelete(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync() - { - return this.DeleteAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteAsync(deleteSnapshotsOption, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, deleteSnapshotsOption, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob did already exist and was deleted; otherwise false. - [DoesServiceRequest] - public bool DeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - if (!exists) - { - return false; - } - - try - { - this.Delete(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } -#endif - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state) - { - return this.BeginDeleteIfExists(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - this.DeleteIfExistsHandler(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] - private void DeleteIfExistsHandler(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult savedExistsResult = this.BeginExists( - options, - operationContext, - existsResult => - { - storageAsyncResult.UpdateCompletedSynchronously(existsResult.CompletedSynchronously); - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - try - { - bool exists = this.EndExists(existsResult); - if (!exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - return; - } - - ICancellableAsyncResult savedDeleteResult = this.BeginDelete( - deleteSnapshotsOption, - accessCondition, - options, - operationContext, - deleteResult => - { - storageAsyncResult.UpdateCompletedSynchronously(deleteResult.CompletedSynchronously); - storageAsyncResult.CancelDelegate = null; - try - { - this.EndDelete(deleteResult); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedDeleteResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }, - null /* state */); - - storageAsyncResult.CancelDelegate = savedExistsResult.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Returns the result of an asynchronous request to delete the blob if it already exists. - /// - /// An that references the pending asynchronous operation. - /// true if the blob did already exist and was deleted; otherwise, false. - public bool EndDeleteIfExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = (StorageAsyncResult)asyncResult; - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DeleteIfExistsAsync(deleteSnapshotsOption, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, deleteSnapshotsOption, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Creates a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// A blob snapshot. - [DoesServiceRequest] - public CloudPageBlob CreateSnapshot(IDictionary metadata = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to create a snapshot of the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateSnapshot(AsyncCallback callback, object state) - { - return this.BeginCreateSnapshot(null /* metadata */, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateSnapshot(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to create a snapshot of the blob. - /// - /// An that references the pending asynchronous operation. - /// A blob snapshot. - public CloudPageBlob EndCreateSnapshot(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync() - { - return this.CreateSnapshotAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateSnapshot, this.EndCreateSnapshot, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateSnapshotAsync(metadata, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateSnapshot, this.EndCreateSnapshot, metadata, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public string AcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AsyncCallback callback, object state) - { - return this.BeginAcquireLease(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to acquire a lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The ID of the acquired lease. - public string EndAcquireLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginAcquireLease, this.EndAcquireLease, leaseTime, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void RenewLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginRenewLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to renew a lease on this blob. - /// - /// An that references the pending asynchronous operation. - public void EndRenewLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.RenewLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginRenewLease, this.EndRenewLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public string ChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginChangeLease(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to change the lease on this blob. - /// - /// An that references the pending asynchronous operation. - /// The new lease ID. - public string EndChangeLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginChangeLease, this.EndChangeLease, proposedLeaseId, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void ReleaseLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, AsyncCallback callback, object state) - { - return this.BeginReleaseLease(accessCondition, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to release the lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - public void EndReleaseLease(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ReleaseLeaseAsync(accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginReleaseLease, this.EndReleaseLease, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public TimeSpan BreakLease(TimeSpan? breakPeriod = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AsyncCallback callback, object state) - { - return this.BeginBreakLease(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to break the current lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// A representing the amount of time before the lease ends, to the second. - public TimeSpan EndBreakLease(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.BreakLeaseAsync(breakPeriod, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginBreakLease, this.EndBreakLease, breakPeriod, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Writes pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void WritePages(Stream pageData, long startOffset, string contentMD5 = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("pageData", pageData); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - - Stream seekableStream = pageData; - if (!pageData.CanSeek || requiresContentMD5) - { - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - Stream writeToStream; - if (pageData.CanSeek) - { - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - long startPosition = seekableStream.Position; - StreamDescriptor streamCopyState = new StreamDescriptor(); - pageData.WriteToSync(writeToStream, null /* copyLength */, Constants.MaxBlockSize, requiresContentMD5, true, tempExecutionState, streamCopyState); - seekableStream.Position = startPosition; - - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - } - - Executor.ExecuteSync( - this.PutPageImpl(seekableStream, startOffset, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginWritePages(Stream pageData, long startOffset, string contentMD5, AsyncCallback callback, object state) - { - return this.BeginWritePages(pageData, startOffset, contentMD5, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginWritePages(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("pageData", pageData); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state); - - if (pageData.CanSeek && !requiresContentMD5) - { - this.WritePagesHandler(pageData, startOffset, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - } - else - { - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - storageAsyncResult.CancelDelegate = tempExecutionState.Cancel; - - Stream seekableStream; - Stream writeToStream; - if (pageData.CanSeek) - { - seekableStream = pageData; - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - long startPosition = seekableStream.Position; - StreamDescriptor streamCopyState = new StreamDescriptor(); - pageData.WriteToAsync( - writeToStream, - null /* copyLength */, - Constants.MaxBlockSize, - requiresContentMD5, - tempExecutionState, - streamCopyState, - completedState => - { - storageAsyncResult.UpdateCompletedSynchronously(completedState.CompletedSynchronously); - - if (completedState.ExceptionRef != null) - { - storageAsyncResult.OnComplete(completedState.ExceptionRef); - } - else - { - try - { - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - - seekableStream.Position = startPosition; - this.WritePagesHandler(seekableStream, startOffset, contentMD5, accessCondition, modifiedOptions, operationContext, storageAsyncResult); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - } - }); - } - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] - private void WritePagesHandler(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, StorageAsyncResult storageAsyncResult) - { - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult result = Executor.BeginExecuteAsync( - this.PutPageImpl(pageData, startOffset, contentMD5, accessCondition, options), - options.RetryPolicy, - operationContext, - ar => - { - storageAsyncResult.UpdateCompletedSynchronously(ar.CompletedSynchronously); - - try - { - Executor.EndExecuteAsync(ar); - storageAsyncResult.OnComplete(); - } - catch (Exception e) - { - storageAsyncResult.OnComplete(e); - } - }, - null /* asyncState */); - - storageAsyncResult.CancelDelegate = result.Cancel; - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.Cancel(); - } - } - } - - /// - /// Ends an asynchronous operation to write pages to a page blob. - /// - /// An that references the pending asynchronous operation. - public void EndWritePages(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = (StorageAsyncResult)asyncResult; - storageAsyncResult.End(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task WritePagesAsync(Stream pageData, long startOffset, string contentMD5) - { - return this.WritePagesAsync(pageData, startOffset, contentMD5, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task WritePagesAsync(Stream pageData, long startOffset, string contentMD5, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginWritePages, this.EndWritePages, pageData, startOffset, contentMD5, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task WritePagesAsync(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.WritePagesAsync(pageData, startOffset, contentMD5, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to write pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task WritePagesAsync(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginWritePages, this.EndWritePages, pageData, startOffset, contentMD5, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Clears pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void ClearPages(long startOffset, long length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - this.ClearPageImpl(startOffset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginClearPages(long startOffset, long length, AsyncCallback callback, object state) - { - return this.BeginClearPages(startOffset, length, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginClearPages(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - this.ClearPageImpl(startOffset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to clear pages from a page blob. - /// - /// An that references the pending asynchronous operation. - public void EndClearPages(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearPagesAsync(long startOffset, long length) - { - return this.ClearPagesAsync(startOffset, length, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearPagesAsync(long startOffset, long length, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginClearPages, this.EndClearPages, startOffset, length, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearPagesAsync(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.ClearPagesAsync(startOffset, length, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to clear pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearPagesAsync(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginClearPages, this.EndClearPages, startOffset, length, accessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public string StartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition = null, AccessCondition destAccessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.ExecuteSync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public string StartCopyFromBlob(CloudPageBlob source, AccessCondition sourceAccessCondition = null, AccessCondition destAccessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - return this.StartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(source, null /* sourceAccessCondition */, null /* destAccessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The source blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(CloudPageBlob source, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), callback, state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Begins an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - [DoesServiceRequest] - public ICancellableAsyncResult BeginStartCopyFromBlob(CloudPageBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginStartCopyFromBlob(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// An that references the pending asynchronous operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - public string EndStartCopyFromBlob(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source) - { - return this.StartCopyFromBlobAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudPageBlob source) - { - return this.StartCopyFromBlobAsync(source, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudPageBlob source, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(source, sourceAccessCondition, destAccessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, sourceAccessCondition, destAccessCondition, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudPageBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(source, sourceAccessCondition, destAccessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task StartCopyFromBlobAsync(CloudPageBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginStartCopyFromBlob, this.EndStartCopyFromBlob, source, sourceAccessCondition, destAccessCondition, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void AbortCopy(string copyId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - Executor.ExecuteSync( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAbortCopy(string copyId, AsyncCallback callback, object state) - { - return this.BeginAbortCopy(copyId, null /* accessCondition */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAbortCopy(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return Executor.BeginExecuteAsync( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to abort an ongoing blob copy operation. - /// - /// An that references the pending asynchronous operation. - public void EndAbortCopy(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId) - { - return this.AbortCopyAsync(copyId, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAbortCopy, this.EndAbortCopy, copyId, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.AbortCopyAsync(copyId, accessCondition, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAbortCopy, this.EndAbortCopy, copyId, accessCondition, options, operationContext, cancellationToken); - } -#endif - - /// - /// Implements the Create method. - /// - /// The size in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the blob. - private RESTCommand CreateImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Put(uri, serverTimeout, this.Properties, BlobType.PageBlob, sizeInBytes, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Resize method. - /// - /// The size in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand ResizeImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Resize(uri, serverTimeout, sizeInBytes, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - this.Properties.Length = sizeInBytes; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetSequenceNumber method. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if this operation is an increment action. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the sequence number. - private RESTCommand SetSequenceNumberImpl(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.SetSequenceNumber(uri, serverTimeout, sequenceNumberAction, sequenceNumber, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the CreateSnapshot method. - /// - /// A collection of name-value pairs defining the metadata of the snapshot, or null. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the snapshot. - /// If the metadata parameter is null then no metadata is associated with the request. - private RESTCommand CreateSnapshotImpl(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Snapshot(uri, serverTimeout, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => - { - if (metadata != null) - { - BlobHttpWebRequestFactory.AddMetadata(r, metadata); - } - }; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp)); - CloudPageBlob snapshot = new CloudPageBlob(this.Name, snapshotTime, this.Container); - snapshot.attributes.Metadata = new Dictionary(metadata ?? this.Metadata); - snapshot.attributes.Properties = new BlobProperties(this.Properties); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(snapshot.attributes, resp); - return snapshot; - }; - - return putCmd; - } - - /// - /// Gets the page ranges impl. - /// - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A for getting the page ranges. - private RESTCommand> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.GetPageRanges(uri, serverTimeout, this.SnapshotTime, offset, length, accessCondition, ctx); - getCmd.SetHeaders = (r, ctx) => BlobHttpWebRequestFactory.AddMetadata(r, this.Metadata); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); - IEnumerable pageRanges = new List(getPageRangesResponse.PageRanges); - return pageRanges; - }; - - return getCmd; - } - - /// - /// Implementation method for the WritePage methods. - /// - /// The page data. - /// The start offset. - /// The content MD5. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that writes the pages. - private RESTCommand PutPageImpl(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - if (startOffset % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("startOffset", startOffset); - } - - long offset = pageData.Position; - long length = pageData.Length - offset; - - PageRange pageRange = new PageRange(startOffset, startOffset + length - 1); - PageWrite pageWrite = PageWrite.Update; - - if ((1 + pageRange.EndOffset - pageRange.StartOffset) % Constants.PageSize != 0 || - (1 + pageRange.EndOffset - pageRange.StartOffset) == 0) - { - CommonUtility.ArgumentOutOfRange("pageData", pageData); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.SendStream = pageData; - putCmd.RecoveryAction = (cmd, ex, ctx) => RecoveryActions.SeekStream(cmd, offset); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, ctx); - putCmd.SetHeaders = (r, ctx) => - { - if (!string.IsNullOrEmpty(contentMD5)) - { - r.Headers[HttpRequestHeader.ContentMd5] = contentMD5; - } - }; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation method for the ClearPage methods. - /// - /// The start offset. Must be multiples of 512. - /// Length of the data range to be cleared. Must be multiples of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that writes the pages. - private RESTCommand ClearPageImpl(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("options", options); - - if (startOffset < 0 || startOffset % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("startOffset", startOffset); - } - - if (length <= 0 || length % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("length", length); - } - - PageRange pageRange = new PageRange(startOffset, startOffset + length - 1); - PageWrite pageWrite = PageWrite.Clear; - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.PutPage(uri, serverTimeout, pageRange, pageWrite, accessCondition, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/ICloudBlob.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/ICloudBlob.cs deleted file mode 100644 index 3de275e49063d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/ICloudBlob.cs +++ /dev/null @@ -1,1849 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Threading; - using System.Threading.Tasks; - - /// - /// An interface required for Windows Azure blob types. The and classes implement the interface. - /// - public partial interface ICloudBlob : IListBlobItem - { -#if SYNC - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - /// On the object returned by this method, the method must be called exactly once for every call. Failing to end a read process before beginning another read can cause unknown behavior. - Stream OpenRead(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginOpenRead(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginOpenRead(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to open a stream for reading from the blob. - /// - /// An that references the pending asynchronous operation. - /// A stream to be used for reading from the blob. - Stream EndOpenRead(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A object that represents the current operation. - Task OpenReadAsync(); - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task OpenReadAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to open a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Uploads a stream to the Windows Azure Blob Service. - /// - /// The stream providing the blob content. Use a seek-able stream for optimal performance. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void UploadFromStream(Stream source, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); - - /// - /// Uploads a stream to the Windows Azure Blob Service. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void UploadFromStream(Stream source, long length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromStream(Stream source, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromStream(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to upload a stream to a blob. - /// - /// An that references the pending asynchronous operation. - void EndUploadFromStream(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, long length); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, long length, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to upload a stream to a blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromStreamAsync(Stream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Uploads a file to the Windows Azure Blob Service. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void UploadFromFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to upload a file to a blob. - /// - /// An that references the pending asynchronous operation. - void EndUploadFromFile(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A object that represents the current operation. - Task UploadFromFileAsync(string path, FileMode mode); - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromFileAsync(string path, FileMode mode, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to upload a file to a blob. - /// - /// The file providing the blob content. - /// A constant that determines how to open the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void UploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginUploadFromByteArray(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An that references the pending asynchronous operation. - void EndUploadFromByteArray(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A object that represents the current operation. - Task UploadFromByteArrayAsync(byte[] buffer, int index, int count); - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to upload the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task UploadFromByteArrayAsync(byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void DownloadToStream(Stream target, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToStream(Stream target, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToStream(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to download the contents of a blob to a stream. - /// - /// An that references the pending asynchronous operation. - void EndDownloadToStream(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A object that represents the current operation. - Task DownloadToStreamAsync(Stream target); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToStreamAsync(Stream target, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToStreamAsync(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void DownloadToFile(string path, FileMode mode, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToFile(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to download the contents of a blob to a file. - /// - /// An that references the pending asynchronous operation. - void EndDownloadToFile(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A object that represents the current operation. - Task DownloadToFileAsync(string path, FileMode mode); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToFileAsync(string path, FileMode mode, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a file. - /// - /// The target file. - /// A constant that determines how to open or create the file. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToFileAsync(string path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - int DownloadToByteArray(byte[] target, int index, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadToByteArray(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to download the contents of a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - int EndDownloadToByteArray(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A object that represents the current operation. - Task DownloadToByteArrayAsync(byte[] target, int index); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToByteArrayAsync(byte[] target, int index, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to download the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadToByteArrayAsync(byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void DownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadRangeToStream(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// An that references the pending asynchronous operation. - void EndDownloadRangeToStream(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// A object that represents the current operation. - Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadRangeToStreamAsync(Stream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - int DownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDownloadRangeToByteArray(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// An that references the pending asynchronous operation. - /// The total number of bytes read into the buffer. - int EndDownloadRangeToByteArray(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// A object that represents the current operation. - Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to download a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DownloadRangeToByteArrayAsync(byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Checks existence of the blob. - /// - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - bool Exists(BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginExists(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous request to check existence of the blob. - /// - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginExists(BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Returns the asynchronous result of the request to check existence of the blob. - /// - /// An that references the pending asynchronous operation. - /// true if the blob exists. - bool EndExists(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A object that represents the current operation. - Task ExistsAsync(); - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ExistsAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous request to check existence of the blob. - /// - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ExistsAsync(BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void FetchAttributes(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginFetchAttributes(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginFetchAttributes(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to populate the blob's properties and metadata. - /// - /// An that references the pending asynchronous operation. - void EndFetchAttributes(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A object that represents the current operation. - Task FetchAttributesAsync(); - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task FetchAttributesAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to populate the blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void SetMetadata(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginSetMetadata(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginSetMetadata(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to update the blob's metadata. - /// - /// An that references the pending asynchronous operation. - void EndSetMetadata(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A object that represents the current operation. - Task SetMetadataAsync(); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task SetMetadataAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's metadata. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void SetProperties(AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginSetProperties(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginSetProperties(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to update the blob's properties. - /// - /// An that references the pending asynchronous operation. - void EndSetProperties(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A object that represents the current operation. - Task SetPropertiesAsync(); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task SetPropertiesAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to update the blob's properties. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void Delete(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDelete(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to delete the blob. - /// - /// An that references the pending asynchronous operation. - void EndDelete(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A object that represents the current operation. - Task DeleteAsync(); - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DeleteAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to delete the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob did not already exist and was created; otherwise false. - bool DeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption = DeleteSnapshotsOption.None, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state); - - /// - /// Begins an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginDeleteIfExists(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Returns the result of an asynchronous request to delete the blob if it already exists. - /// - /// An that references the pending asynchronous operation. - /// true if the blob did not already exist and was created; otherwise, false. - bool EndDeleteIfExists(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A object that represents the current operation. - Task DeleteIfExistsAsync(); - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DeleteIfExistsAsync(CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous request to delete the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - string AcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginAcquireLease(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to acquire a lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// The ID of the acquired lease. - string EndAcquireLease(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// A object that represents the current operation. - Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId); - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to acquire a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - void RenewLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginRenewLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to renew a lease on this blob. - /// - /// An that references the pending asynchronous operation. - void EndRenewLease(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - Task RenewLeaseAsync(AccessCondition accessCondition); - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task RenewLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to renew a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// The new lease ID. - string ChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginChangeLease(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to change the lease on this blob. - /// - /// An that references the pending asynchronous operation. - /// The new lease ID. - string EndChangeLease(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition); - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to change the lease on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - void ReleaseLease(AccessCondition accessCondition, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginReleaseLease(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to release the lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - void EndReleaseLease(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that represents the current operation. - Task ReleaseLeaseAsync(AccessCondition accessCondition); - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ReleaseLeaseAsync(AccessCondition accessCondition, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to release the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - TimeSpan BreakLease(TimeSpan? breakPeriod = null, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// An optional callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginBreakLease(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to break the current lease on this blob. - /// - /// An IAsyncResult that references the pending asynchronous operation. - /// A representing the amount of time before the lease ends, to the second. - TimeSpan EndBreakLease(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// A object that represents the current operation. - Task BreakLeaseAsync(TimeSpan? breakPeriod); - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task BreakLeaseAsync(TimeSpan? breakPeriod, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to break the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An object that represents the access conditions for the blob. - /// The options for this operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. - /// An object that represents the access conditions for the destination blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - string StartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition = null, AccessCondition destAccessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. - /// An object that represents the access conditions for the destination blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - ICancellableAsyncResult BeginStartCopyFromBlob(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to request that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// An that references the pending asynchronous operation. - /// The copy ID associated with the copy operation. - string EndStartCopyFromBlob(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A object that represents the current operation. - Task StartCopyFromBlobAsync(Uri source); - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task StartCopyFromBlobAsync(Uri source, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. - /// An object that represents the access conditions for the destination blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to request that the service start to copy another blob's contents, properties, and metadata - /// to the blob referenced by this object. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. - /// An object that represents the access conditions for the destination blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - Task StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - -#if SYNC - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - void AbortCopy(string copyId, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null); -#endif - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginAbortCopy(string copyId, AsyncCallback callback, object state); - - /// - /// Begins an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - ICancellableAsyncResult BeginAbortCopy(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state); - - /// - /// Ends an asynchronous operation to abort an ongoing blob copy operation. - /// - /// An that references the pending asynchronous operation. - void EndAbortCopy(IAsyncResult asyncResult); - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A object that represents the current operation. - Task AbortCopyAsync(string copyId); - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task AbortCopyAsync(string copyId, CancellationToken cancellationToken); - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Returns a task that performs an asynchronous operation to abort an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - Task AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken); -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpResponseParsers.cs deleted file mode 100644 index 1e85aad841e71..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpResponseParsers.cs +++ /dev/null @@ -1,240 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// -// Contains code for the CloudStorageAccount class. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Net; - - /// - /// Provides a set of methods for parsing a response containing blob data from the Blob service. - /// - public static partial class BlobHttpResponseParsers - { - /// - /// Gets the request ID from the response. - /// - /// The web response. - /// A unique value associated with the request. - public static string GetRequestId(HttpWebResponse response) - { - return Response.GetRequestId(response); - } - - /// - /// Gets the blob's properties from the response. - /// - /// The web response. - /// The blob's properties. - public static BlobProperties GetProperties(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - BlobProperties properties = new BlobProperties(); - properties.ETag = HttpResponseParsers.GetETag(response); - -#if WINDOWS_PHONE - properties.LastModified = HttpResponseParsers.GetLastModified(response); - properties.ContentLanguage = response.Headers[Constants.HeaderConstants.ContentLanguageHeader]; -#else - properties.LastModified = response.LastModified.ToUniversalTime(); - properties.ContentLanguage = response.Headers[HttpResponseHeader.ContentLanguage]; -#endif - - properties.ContentEncoding = response.Headers[HttpResponseHeader.ContentEncoding]; - properties.ContentMD5 = response.Headers[HttpResponseHeader.ContentMd5]; - properties.ContentType = response.Headers[HttpResponseHeader.ContentType]; - properties.CacheControl = response.Headers[HttpResponseHeader.CacheControl]; - - // Get blob type - string blobType = response.Headers[Constants.HeaderConstants.BlobType]; - if (!string.IsNullOrEmpty(blobType)) - { - properties.BlobType = (BlobType)Enum.Parse(typeof(BlobType), blobType, true); - } - - // Get lease properties - properties.LeaseStatus = GetLeaseStatus(response); - properties.LeaseState = GetLeaseState(response); - properties.LeaseDuration = GetLeaseDuration(response); - - // Get the content length. Prioritize range and x-ms over content length for the special cases. - string rangeHeader = response.Headers[HttpResponseHeader.ContentRange]; - string contentLengthHeader = response.Headers[Constants.HeaderConstants.ContentLengthHeader]; - string blobContentLengthHeader = response.Headers[Constants.HeaderConstants.BlobContentLengthHeader]; - if (!string.IsNullOrEmpty(rangeHeader)) - { - properties.Length = long.Parse(rangeHeader.Split('/')[1], CultureInfo.InvariantCulture); - } - else if (!string.IsNullOrEmpty(blobContentLengthHeader)) - { - properties.Length = long.Parse(blobContentLengthHeader, CultureInfo.InvariantCulture); - } - else if (!string.IsNullOrEmpty(contentLengthHeader)) - { - // On Windows Phone, ContentLength property is not always same as Content-Length header, - // so we try to parse the header first. - properties.Length = long.Parse(contentLengthHeader, CultureInfo.InvariantCulture); - } - else - { - properties.Length = response.ContentLength; - } - - // Get sequence number - string sequenceNumber = response.Headers[Constants.HeaderConstants.BlobSequenceNumber]; - if (!string.IsNullOrEmpty(sequenceNumber)) - { - properties.PageBlobSequenceNumber = long.Parse(sequenceNumber, CultureInfo.InvariantCulture); - } - - return properties; - } - - /// - /// Extracts the lease status from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseStatus GetLeaseStatus(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - string leaseStatus = response.Headers[Constants.HeaderConstants.LeaseStatus]; - return GetLeaseStatus(leaseStatus); - } - - /// - /// Extracts the lease state from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseState GetLeaseState(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - string leaseState = response.Headers[Constants.HeaderConstants.LeaseState]; - return GetLeaseState(leaseState); - } - - /// - /// Extracts the lease duration from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseDuration GetLeaseDuration(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - string leaseDuration = response.Headers[Constants.HeaderConstants.LeaseDurationHeader]; - return GetLeaseDuration(leaseDuration); - } - - /// - /// Extracts the lease ID header from a web response. - /// - /// The web response. - /// The lease ID. - public static string GetLeaseId(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - return response.Headers[Constants.HeaderConstants.LeaseIdHeader]; - } - - /// - /// Extracts the remaining lease time from a web response. - /// - /// The web response. - /// The remaining lease time, in seconds. - public static int? GetRemainingLeaseTime(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - int remainingLeaseTime; - if (int.TryParse(response.Headers[Constants.HeaderConstants.LeaseTimeHeader], out remainingLeaseTime)) - { - return remainingLeaseTime; - } - else - { - return null; - } - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - public static IDictionary GetMetadata(HttpWebResponse response) - { - return HttpResponseParsers.GetMetadata(response); - } - - /// - /// Extracts a object from the headers of a web response. - /// - /// The HTTP web response. - /// A object, or null if the web response does not contain a copy status. - public static CopyState GetCopyAttributes(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - string copyStatusString = response.Headers[Constants.HeaderConstants.CopyStatusHeader]; - if (!string.IsNullOrEmpty(copyStatusString)) - { - return GetCopyAttributes( - copyStatusString, - response.Headers[Constants.HeaderConstants.CopyIdHeader], - response.Headers[Constants.HeaderConstants.CopySourceHeader], - response.Headers[Constants.HeaderConstants.CopyProgressHeader], - response.Headers[Constants.HeaderConstants.CopyCompletionTimeHeader], - response.Headers[Constants.HeaderConstants.CopyDescriptionHeader]); - } - else - { - return null; - } - } - - /// - /// Gets the snapshot timestamp from the response. - /// - /// The web response. - /// The snapshot timestamp. - public static string GetSnapshotTime(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - return response.Headers[Constants.HeaderConstants.SnapshotHeader]; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpWebRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpWebRequestFactory.cs deleted file mode 100644 index 24bf27d435bdf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/BlobHttpWebRequestFactory.cs +++ /dev/null @@ -1,722 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Net; - - /// - /// A factory class for constructing a web request to manage blobs in the Blob service. - /// - public static class BlobHttpWebRequestFactory - { - /// - /// Creates a web request to get the properties of the Blob service. - /// - /// The absolute URI to the Blob service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to get the Blob service properties. - /// - public static HttpWebRequest GetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.GetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Creates a web request to set the properties of the Blob service. - /// - /// The absolute URI to the Blob service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to set the Blob service properties. - /// - public static HttpWebRequest SetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.SetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Writes Blob service properties to a stream, formatted in XML. - /// - /// The service properties to format and write to the stream. - /// The stream to which the formatted properties are to be written. - public static void WriteServiceProperties(ServiceProperties properties, Stream outputStream) - { - CommonUtility.AssertNotNull("properties", properties); - - properties.WriteServiceProperties(outputStream); - } - - /// - /// Constructs a web request to create a new block blob or page blob, or to update the content - /// of an existing block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The properties to set for the blob. - /// The type of the blob. - /// For a page blob, the size of the blob. This parameter is ignored - /// for block blobs. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Put(Uri uri, int? timeout, BlobProperties properties, BlobType blobType, long pageBlobSize, AccessCondition accessCondition, OperationContext operationContext) - { - CommonUtility.AssertNotNull("properties", properties); - - if (blobType == BlobType.Unspecified) - { - throw new InvalidOperationException(SR.UndefinedBlobType); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, null /* builder */, operationContext); - - if (properties.CacheControl != null) - { - request.Headers[HttpRequestHeader.CacheControl] = properties.CacheControl; - } - - if (properties.ContentType != null) - { - // Setting it using Headers is an exception - request.ContentType = properties.ContentType; - } - - if (properties.ContentMD5 != null) - { - request.Headers[HttpRequestHeader.ContentMd5] = properties.ContentMD5; - } - - if (properties.ContentLanguage != null) - { - request.Headers[HttpRequestHeader.ContentLanguage] = properties.ContentLanguage; - } - - if (properties.ContentEncoding != null) - { - request.Headers[HttpRequestHeader.ContentEncoding] = properties.ContentEncoding; - } - - if (blobType == BlobType.PageBlob) - { - request.Headers[Constants.HeaderConstants.BlobType] = Constants.HeaderConstants.PageBlob; - request.Headers[Constants.HeaderConstants.BlobContentLengthHeader] = pageBlobSize.ToString(NumberFormatInfo.InvariantInfo); - properties.Length = pageBlobSize; - } - else - { - request.Headers[Constants.HeaderConstants.BlobType] = Constants.HeaderConstants.BlockBlob; - } - - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Adds the snapshot. - /// - /// An object of type that contains additional parameters to add to the URI query string. - /// The snapshot version, if the blob is a snapshot. - private static void AddSnapshot(UriQueryBuilder builder, DateTimeOffset? snapshot) - { - if (snapshot.HasValue) - { - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(snapshot.Value)); - } - } - - /// - /// Constructs a web request to return the list of valid page ranges for a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest GetPageRanges(Uri uri, int? timeout, DateTimeOffset? snapshot, long? offset, long? count, AccessCondition accessCondition, OperationContext operationContext) - { - if (offset.HasValue) - { - CommonUtility.AssertNotNull("count", count); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "pagelist"); - BlobHttpWebRequestFactory.AddSnapshot(builder, snapshot); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - AddRange(request, offset, count); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds the Range Header for Blob Service Operations. - /// - /// Request - /// Starting byte of the range - /// Number of bytes in the range - private static void AddRange(HttpWebRequest request, long? offset, long? count) - { - if (count.HasValue) - { - CommonUtility.AssertNotNull("offset", offset); - CommonUtility.AssertInBounds("count", count.Value, 1, long.MaxValue); - } - - if (offset.HasValue) - { - string rangeStart = offset.ToString(); - string rangeEnd = string.Empty; - if (count.HasValue) - { - rangeEnd = (offset + count.Value - 1).ToString(); - } - - string rangeHeaderValue = string.Format(CultureInfo.InvariantCulture, Constants.HeaderConstants.RangeHeaderFormat, rangeStart, rangeEnd); - request.Headers.Add(Constants.HeaderConstants.RangeHeader, rangeHeaderValue); - } - } - - /// - /// Constructs a web request to return the blob's system properties. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest GetProperties(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpWebRequestFactory.AddSnapshot(builder, snapshot); - - HttpWebRequest request = HttpWebRequestFactory.GetProperties(uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set system properties for a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The blob's properties. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest SetProperties(Uri uri, int? timeout, BlobProperties properties, AccessCondition accessCondition, OperationContext operationContext) - { - CommonUtility.AssertNotNull("properties", properties); - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - request.AddOptionalHeader(Constants.HeaderConstants.CacheControlHeader, properties.CacheControl); - request.AddOptionalHeader(Constants.HeaderConstants.ContentEncodingHeader, properties.ContentEncoding); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentLanguageHeader, properties.ContentLanguage); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentMD5Header, properties.ContentMD5); - request.AddOptionalHeader(Constants.HeaderConstants.ContentTypeHeader, properties.ContentType); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to resize a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The new blob size, if the blob is a page blob. Set this parameter to null to keep the existing blob size. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Resize(Uri uri, int? timeout, long newBlobSize, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - request.Headers.Add(Constants.HeaderConstants.BlobContentLengthHeader, newBlobSize.ToString(NumberFormatInfo.InvariantInfo)); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set a page blob's sequence number. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if this operation is an increment action. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest SetSequenceNumber(Uri uri, int? timeout, SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, OperationContext operationContext) - { - CommonUtility.AssertInBounds("sequenceNumberAction", sequenceNumberAction, SequenceNumberAction.Max, SequenceNumberAction.Increment); - if (sequenceNumberAction == SequenceNumberAction.Increment) - { - if (sequenceNumber.HasValue) - { - throw new ArgumentException(SR.BlobInvalidSequenceNumber, "sequenceNumber"); - } - } - else - { - CommonUtility.AssertNotNull("sequenceNumber", sequenceNumber); - CommonUtility.AssertInBounds("sequenceNumber", sequenceNumber.Value, 0); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - request.ContentLength = 0; - - request.Headers.Add(Constants.HeaderConstants.SequenceNumberAction, sequenceNumberAction.ToString()); - if (sequenceNumberAction != SequenceNumberAction.Increment) - { - request.Headers.Add(Constants.HeaderConstants.BlobSequenceNumber, sequenceNumber.Value.ToString(CultureInfo.InvariantCulture)); - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to return the user-defined metadata for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest GetMetadata(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpWebRequestFactory.AddSnapshot(builder, snapshot); - - HttpWebRequest request = HttpWebRequestFactory.GetMetadata(uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set user-defined metadata for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest SetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.SetMetadata(uri, timeout, null /* builder */, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpWebRequest request, IDictionary metadata) - { - HttpWebRequestFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpWebRequest request, string name, string value) - { - HttpWebRequestFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to delete a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// A set of options indicating whether to delete only blobs, only snapshots, or both. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "deleteSnapshotsOption", Justification = "Splitting the option name in this case could be confusing")] - public static HttpWebRequest Delete(Uri uri, int? timeout, DateTimeOffset? snapshot, DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, OperationContext operationContext) - { - if ((snapshot != null) && (deleteSnapshotsOption != DeleteSnapshotsOption.None)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, SR.DeleteSnapshotsNotValidError, "deleteSnapshotsOption", "snapshot")); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpWebRequestFactory.AddSnapshot(builder, snapshot); - - HttpWebRequest request = HttpWebRequestFactory.Delete(uri, builder, timeout, operationContext); - - switch (deleteSnapshotsOption) - { - case DeleteSnapshotsOption.None: - break; // nop - - case DeleteSnapshotsOption.IncludeSnapshots: - request.Headers.Add( - Constants.HeaderConstants.DeleteSnapshotHeader, - Constants.HeaderConstants.IncludeSnapshotsValue); - break; - - case DeleteSnapshotsOption.DeleteSnapshotsOnly: - request.Headers.Add( - Constants.HeaderConstants.DeleteSnapshotHeader, - Constants.HeaderConstants.SnapshotsOnlyValue); - break; - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to create a snapshot of a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Snapshot(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "snapshot"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to use to acquire, renew, change, release or break the lease for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval, in seconds. - /// The lease action to perform. - /// A lease ID to propose for the result of an acquire or change operation, - /// or null if no ID is proposed for an acquire operation. This should be null for renew, release, and break operations. - /// The lease duration, in seconds, for acquire operations. - /// If this is -1 then an infinite duration is specified. This should be null for renew, change, release, and break operations. - /// The amount of time to wait, in seconds, after a break operation before the lease is broken. - /// If this is null then the default time is used. This should be null for acquire, renew, change, and release operations. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Lease(Uri uri, int? timeout, LeaseAction action, string proposedLeaseId, int? leaseDuration, int? leaseBreakPeriod, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "lease"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - - // Add lease headers - BlobHttpWebRequestFactory.AddLeaseAction(request, action); - BlobHttpWebRequestFactory.AddLeaseDuration(request, leaseDuration); - BlobHttpWebRequestFactory.AddProposedLeaseId(request, proposedLeaseId); - BlobHttpWebRequestFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod); - - return request; - } - - /// - /// Adds a proposed lease id to a request. - /// - /// The request. - /// The proposed lease id. - internal static void AddProposedLeaseId(HttpWebRequest request, string proposedLeaseId) - { - request.AddOptionalHeader(Constants.HeaderConstants.ProposedLeaseIdHeader, proposedLeaseId); - } - - /// - /// Adds a lease duration to a request. - /// - /// The request. - /// The lease duration. - internal static void AddLeaseDuration(HttpWebRequest request, int? leaseDuration) - { - request.AddOptionalHeader(Constants.HeaderConstants.LeaseDurationHeader, leaseDuration); - } - - /// - /// Adds a lease break period to a request. - /// - /// The request. - /// The lease break period. - internal static void AddLeaseBreakPeriod(HttpWebRequest request, int? leaseBreakPeriod) - { - request.AddOptionalHeader(Constants.HeaderConstants.LeaseBreakPeriodHeader, leaseBreakPeriod); - } - - /// - /// Adds a lease action to a request. - /// - /// The request. - /// The lease action. - [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "ToLower(CultureInfo) is not present in RT and ToLowerInvariant() also violates FxCop")] - internal static void AddLeaseAction(HttpWebRequest request, LeaseAction leaseAction) - { - request.Headers.Add(Constants.HeaderConstants.LeaseActionHeader, leaseAction.ToString().ToLower()); - } - - /// - /// Constructs a web request to write a block to a block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The block ID for this block. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest PutBlock(Uri uri, int? timeout, string blockId, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "block"); - builder.Add("blockid", blockId); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - request.ApplyLeaseId(accessCondition); - return request; - } - - /// - /// Constructs a web request to create or update a blob by committing a block list. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The properties to set for the blob. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest PutBlockList(Uri uri, int? timeout, BlobProperties properties, AccessCondition accessCondition, OperationContext operationContext) - { - CommonUtility.AssertNotNull("properties", properties); - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "blocklist"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - request.AddOptionalHeader(Constants.HeaderConstants.CacheControlHeader, properties.CacheControl); - request.AddOptionalHeader(Constants.HeaderConstants.ContentTypeHeader, properties.ContentType); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentMD5Header, properties.ContentMD5); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentLanguageHeader, properties.ContentLanguage); - request.AddOptionalHeader(Constants.HeaderConstants.ContentEncodingHeader, properties.ContentEncoding); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to return the list of blocks for a block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The types of blocks to include in the list: committed, uncommitted, or both. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetBlockList(Uri uri, int? timeout, DateTimeOffset? snapshot, BlockListingFilter typesOfBlocks, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "blocklist"); - builder.Add("blocklisttype", typesOfBlocks.ToString()); - BlobHttpWebRequestFactory.AddSnapshot(builder, snapshot); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to write or clear a range of pages in a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The page range, defined by an object of type . - /// A value of type , indicating the operation to perform on the page blob. - /// The to apply to the request. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest PutPage(Uri uri, int? timeout, PageRange pageRange, PageWrite pageWrite, AccessCondition accessCondition, OperationContext operationContext) - { - CommonUtility.AssertNotNull("pageRange", pageRange); - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "page"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - request.Headers.Add(Constants.HeaderConstants.RangeHeader, pageRange.ToString()); - request.Headers.Add(Constants.HeaderConstants.PageWrite, pageWrite.ToString()); - - request.ApplyAccessCondition(accessCondition); - request.ApplySequenceNumberCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to copy a blob. - /// - /// The absolute URI to the destination blob. - /// The server timeout interval. - /// The absolute URI to the source blob, including any necessary authentication parameters. - /// The access condition to apply to the source blob. - /// The access condition to apply to the destination blob. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dest", Justification = "Reviewed")] - public static HttpWebRequest CopyFrom(Uri uri, int? timeout, Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, null /* builder */, operationContext); - - request.Headers.Add(Constants.HeaderConstants.CopySourceHeader, source.AbsoluteUri); - request.ApplyAccessCondition(destAccessCondition); - request.ApplyAccessConditionToSource(sourceAccessCondition); - - return request; - } - - /// - /// Generates a web request to abort a copy operation. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The ID string of the copy operation to be aborted. - /// The access condition to apply to the request. Only lease conditions are supported for this operation. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest AbortCopy(Uri uri, int? timeout, string copyId, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "copy"); - builder.Add(Constants.QueryConstants.CopyId, copyId); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - request.Headers.Add(Constants.HeaderConstants.CopyActionHeader, Constants.HeaderConstants.CopyActionAbort); - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Constructs a web request to get the blob's content, properties, and metadata. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot version, if the blob is a snapshot. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request for performing the operation. - public static HttpWebRequest Get(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - if (snapshot.HasValue) - { - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(snapshot.Value)); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to return a specified range of the blob's content, together with its properties and metadata. - /// - /// The absolute URI to the blob. - /// The server timeout interval, in seconds. - /// The snapshot version, if the blob is a snapshot. - /// The byte offset at which to begin returning content. - /// The number of bytes to return, or null to return all bytes through the end of the blob. - /// If set to true, request an MD5 header for the specified range. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest Get(Uri uri, int? timeout, DateTimeOffset? snapshot, long? offset, long? count, bool rangeContentMD5, AccessCondition accessCondition, OperationContext operationContext) - { - if (offset.HasValue && offset.Value < 0) - { - CommonUtility.ArgumentOutOfRange("offset", offset); - } - - if (offset.HasValue && rangeContentMD5) - { - CommonUtility.AssertNotNull("count", count); - CommonUtility.AssertInBounds("count", count.Value, 1, Constants.MaxBlockSize); - } - - HttpWebRequest request = Get(uri, timeout, snapshot, accessCondition, operationContext); - AddRange(request, offset, count); - - if (offset.HasValue && rangeContentMD5) - { - request.Headers.Add(Constants.HeaderConstants.RangeContentMD5Header, Constants.HeaderConstants.TrueHeader); - } - - return request; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpResponseParsers.cs deleted file mode 100644 index e947f2f80eb94..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpResponseParsers.cs +++ /dev/null @@ -1,90 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.Collections.Generic; - using System.Net; - - /// - /// Provides a set of methods for parsing container responses from the Blob service. - /// - public static partial class ContainerHttpResponseParsers - { - /// - /// Gets the request ID from the response. - /// - /// The web response. - /// A unique value associated with the request. - public static string GetRequestId(HttpWebResponse response) - { - return Response.GetRequestId(response); - } - - /// - /// Gets the container's properties from the response. - /// - /// The web response. - /// The container's attributes. - public static BlobContainerProperties GetProperties(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - // Set the container properties - BlobContainerProperties containerProperties = new BlobContainerProperties(); - containerProperties.ETag = HttpResponseParsers.GetETag(response); - -#if WINDOWS_PHONE - containerProperties.LastModified = HttpResponseParsers.GetLastModified(response); -#else - containerProperties.LastModified = response.LastModified.ToUniversalTime(); -#endif - - // Get lease properties - containerProperties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(response); - containerProperties.LeaseState = BlobHttpResponseParsers.GetLeaseState(response); - containerProperties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(response); - - return containerProperties; - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - public static IDictionary GetMetadata(HttpWebResponse response) - { - return HttpResponseParsers.GetMetadata(response); - } - - /// - /// Gets the ACL for the container from the response. - /// - /// The web response. - /// A value indicating the public access level for the container. - public static BlobContainerPublicAccessType GetAcl(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - string acl = response.Headers[Constants.HeaderConstants.BlobPublicAccess]; - return GetContainerAcl(acl); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpWebRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpWebRequestFactory.cs deleted file mode 100644 index b3a15c085064e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Blob/Protocol/ContainerHttpWebRequestFactory.cs +++ /dev/null @@ -1,380 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Net; - using System.Text; - - /// - /// A factory class for constructing a web request to manage containers in the Blob service. - /// - public static class ContainerHttpWebRequestFactory - { - /// - /// Constructs a web request to create a new container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Create(Uri uri, int? timeout, OperationContext operationContext) - { - return ContainerHttpWebRequestFactory.Create(uri, timeout, operationContext, BlobContainerPublicAccessType.Off); - } - - /// - /// Constructs a web request to create a new container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// An object for tracking the current operation. - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A web request to use to perform the operation. - public static HttpWebRequest Create(Uri uri, int? timeout, OperationContext operationContext, BlobContainerPublicAccessType accessType) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpWebRequest request = HttpWebRequestFactory.Create(uri, timeout, containerBuilder, operationContext); - - if (accessType != BlobContainerPublicAccessType.Off) - { - request.Headers.Add(Constants.HeaderConstants.ContainerPublicAccessType, accessType.ToString().ToLower(CultureInfo.InvariantCulture)); - } - - return request; - } - - /// - /// Constructs a web request to delete the container and all of the blobs within it. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Delete(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpWebRequest request = HttpWebRequestFactory.Delete(uri, containerBuilder, timeout, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return the user-defined metadata for this container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpWebRequest request = HttpWebRequestFactory.GetMetadata(uri, timeout, containerBuilder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return the properties and user-defined metadata for this container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetProperties(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpWebRequest request = HttpWebRequestFactory.GetProperties(uri, timeout, containerBuilder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to set user-defined metadata for the container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest SetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpWebRequest request = HttpWebRequestFactory.SetMetadata(uri, timeout, containerBuilder, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to use to acquire, renew, change, release or break the lease for the container. - /// - /// The absolute URI to the container. - /// The server timeout interval, in seconds. - /// The lease action to perform. - /// A lease ID to propose for the result of an acquire or change operation, - /// or null if no ID is proposed for an acquire operation. This should be null for renew, release, and break operations. - /// The lease duration, in seconds, for acquire operations. - /// If this is -1 then an infinite duration is specified. This should be null for renew, change, release, and break operations. - /// The amount of time to wait, in seconds, after a break operation before the lease is broken. - /// If this is null then the default time is used. This should be null for acquire, renew, change, and release operations. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Lease(Uri uri, int? timeout, LeaseAction action, string proposedLeaseId, int? leaseDuration, int? leaseBreakPeriod, AccessCondition accessCondition, OperationContext operationContext) - { - UriQueryBuilder builder = GetContainerUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "lease"); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - - // Add Headers - BlobHttpWebRequestFactory.AddLeaseAction(request, action); - BlobHttpWebRequestFactory.AddLeaseDuration(request, leaseDuration); - BlobHttpWebRequestFactory.AddProposedLeaseId(request, proposedLeaseId); - BlobHttpWebRequestFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpWebRequest request, IDictionary metadata) - { - HttpWebRequestFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpWebRequest request, string name, string value) - { - HttpWebRequestFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to return a listing of all containers in this storage account. - /// - /// The absolute URI for the account. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// Additional details to return with the listing. - /// An object for tracking the current operation. - /// A web request for the specified operation. - public static HttpWebRequest List(Uri uri, int? timeout, ListingContext listingContext, ContainerListingDetails detailsIncluded, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - } - - if ((detailsIncluded & ContainerListingDetails.Metadata) != 0) - { - builder.Add("include", "metadata"); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetAcl(Uri uri, int? timeout, AccessCondition accessCondition, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.GetAcl(uri, GetContainerUriQueryBuilder(), timeout, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set the ACL for a container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The type of public access to allow for the container. - /// The access condition to apply to the request. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "ToLower(CultureInfo) is not present in RT and ToLowerInvariant() also violates FxCop")] - public static HttpWebRequest SetAcl(Uri uri, int? timeout, BlobContainerPublicAccessType publicAccess, AccessCondition accessCondition, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.SetAcl(uri, GetContainerUriQueryBuilder(), timeout, operationContext); - - if (publicAccess != BlobContainerPublicAccessType.Off) - { - request.Headers.Add(Constants.HeaderConstants.ContainerPublicAccessType, publicAccess.ToString().ToLower()); - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return a listing of all blobs in the container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest ListBlobs(Uri uri, int? timeout, BlobListingContext listingContext, OperationContext operationContext) - { - UriQueryBuilder builder = ContainerHttpWebRequestFactory.GetContainerUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Delimiter != null) - { - builder.Add("delimiter", listingContext.Delimiter); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - - if (listingContext.Details != BlobListingDetails.None) - { - StringBuilder sb = new StringBuilder(); - - bool started = false; - - if ((listingContext.Details & BlobListingDetails.Snapshots) == BlobListingDetails.Snapshots) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("snapshots"); - } - - if ((listingContext.Details & BlobListingDetails.UncommittedBlobs) == BlobListingDetails.UncommittedBlobs) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("uncommittedblobs"); - } - - if ((listingContext.Details & BlobListingDetails.Metadata) == BlobListingDetails.Metadata) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("metadata"); - } - - if ((listingContext.Details & BlobListingDetails.Copy) == BlobListingDetails.Copy) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("copy"); - } - - builder.Add("include", sb.ToString()); - } - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Gets the container Uri query builder. - /// - /// A for the container. - internal static UriQueryBuilder GetContainerUriQueryBuilder() - { - UriQueryBuilder uriBuilder = new UriQueryBuilder(); - uriBuilder.Add(Constants.QueryConstants.ResourceType, "container"); - return uriBuilder; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/ICanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/ICanonicalizer.cs deleted file mode 100644 index d3614acd4f67d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/ICanonicalizer.cs +++ /dev/null @@ -1,47 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using System.Diagnostics.CodeAnalysis; - using System.Net; - - /// - /// Represents a canonicalizer that converts HTTP request data into a standard form appropriate for signing. - /// For detailed information on how to authenticate a request, - /// see Authentication for the Windows Azure Storage Services. - /// - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Canonicalizer", Justification = "Reviewed: Canonicalizer can be used as an identifier name.")] - public interface ICanonicalizer - { - /// - /// Gets the authorization scheme used for canonicalization. - /// - /// The authorization scheme used for canonicalization. - /// Authentication for the Windows Azure Storage Services - string AuthorizationScheme { get; } - - /// - /// Converts the specified HTTP request data into a standard form appropriate for signing. - /// - /// The HTTP request that needs to be signed. - /// The name of the storage account that the HTTP request will access. - /// The canonicalized string containing the HTTP request data in a standard form appropriate for signing. - /// Authentication for the Windows Azure Storage Services - string CanonicalizeHttpRequest(HttpWebRequest request, string accountName); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyCanonicalizer.cs deleted file mode 100644 index 4bb28022eb901..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyCanonicalizer.cs +++ /dev/null @@ -1,107 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System.Diagnostics.CodeAnalysis; - using System.Net; - - /// - /// Represents a canonicalizer that converts HTTP request data into a standard form appropriate for signing via - /// the Shared Key authentication scheme for the Blob or Queue service. - /// - /// Authentication for the Windows Azure Storage Services - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Canonicalizer", Justification = "Reviewed: Canonicalizer can be used as an identifier name.")] - public sealed class SharedKeyCanonicalizer : ICanonicalizer - { - private const string SharedKeyAuthorizationScheme = "SharedKey"; - - private static SharedKeyCanonicalizer instance = new SharedKeyCanonicalizer(); - - /// - /// Gets a static instance of the object. - /// - /// The static instance of the class. - /// Authentication for the Windows Azure Storage Services - public static SharedKeyCanonicalizer Instance - { - get - { - return SharedKeyCanonicalizer.instance; - } - } - - private SharedKeyCanonicalizer() - { - } - - /// - /// Gets the authorization scheme used for canonicalization. - /// - /// The authorization scheme used for canonicalization. - /// Authentication for the Windows Azure Storage Services - public string AuthorizationScheme - { - get - { - return SharedKeyAuthorizationScheme; - } - } - - /// - /// Converts the specified HTTP request data into a standard form appropriate for signing. - /// - /// The HTTP request that needs to be signed. - /// The name of the storage account that the HTTP request will access. - /// The canonicalized string containing the HTTP request data in a standard form appropriate for signing. - /// Authentication for the Windows Azure Storage Services - public string CanonicalizeHttpRequest(HttpWebRequest request, string accountName) - { - CommonUtility.AssertNotNull("request", request); - - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method); - - // Add the Content-* HTTP headers. Empty values are allowed. - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.ContentEncoding]); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.ContentLanguage]); - AuthenticationUtility.AppendCanonicalizedContentLengthHeader(canonicalizedString, request); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.ContentMd5]); - canonicalizedString.AppendCanonicalizedElement(request.ContentType); - - // Add the Date HTTP header (only if the x-ms-date header is not being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request); - - // Add If-* headers and Range header - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.IfModifiedSince]); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.IfMatch]); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.IfNoneMatch]); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.IfUnmodifiedSince]); - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.Range]); - - // Add any custom headers - AuthenticationUtility.AppendCanonicalizedCustomHeaders(canonicalizedString, request); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteCanonicalizer.cs deleted file mode 100644 index 1bb76dc1bca63..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteCanonicalizer.cs +++ /dev/null @@ -1,96 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System.Net; - - /// - /// Represents a canonicalizer that converts HTTP request data into a standard form appropriate for signing via - /// the Shared Key Lite authentication scheme for the Blob or Queue service. - /// - /// Authentication for the Windows Azure Storage Services - public sealed class SharedKeyLiteCanonicalizer : ICanonicalizer - { - private const string SharedKeyLiteAuthorizationScheme = "SharedKeyLite"; - private const int ExpectedCanonicalizedStringLength = 250; - - private static SharedKeyLiteCanonicalizer instance = new SharedKeyLiteCanonicalizer(); - - /// - /// Gets a static instance of the object. - /// - /// The static instance of the class. - /// Authentication for the Windows Azure Storage Services - public static SharedKeyLiteCanonicalizer Instance - { - get - { - return SharedKeyLiteCanonicalizer.instance; - } - } - - private SharedKeyLiteCanonicalizer() - { - } - - /// - /// Gets the authorization scheme used for canonicalization. - /// - /// The authorization scheme used for canonicalization. - /// Authentication for the Windows Azure Storage Services - public string AuthorizationScheme - { - get - { - return SharedKeyLiteAuthorizationScheme; - } - } - - /// - /// Converts the specified HTTP request data into a standard form appropriate for signing. - /// - /// The HTTP request that needs to be signed. - /// The name of the storage account that the HTTP request will access. - /// The canonicalized string containing the HTTP request data in a standard form appropriate for signing. - /// Authentication for the Windows Azure Storage Services - public string CanonicalizeHttpRequest(HttpWebRequest request, string accountName) - { - CommonUtility.AssertNotNull("request", request); - - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method, ExpectedCanonicalizedStringLength); - - // Add the Content-* HTTP headers. Empty values are allowed. - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.ContentMd5]); - canonicalizedString.AppendCanonicalizedElement(request.ContentType); - - // Add the Date HTTP header (only if the x-ms-date header is not being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request); - - // Add any custom headers - AuthenticationUtility.AppendCanonicalizedCustomHeaders(canonicalizedString, request); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteTableCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteTableCanonicalizer.cs deleted file mode 100644 index 5907ceb1e5663..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyLiteTableCanonicalizer.cs +++ /dev/null @@ -1,89 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System.Diagnostics.CodeAnalysis; - using System.Net; - - /// - /// Represents a canonicalizer that converts HTTP request data into a standard form appropriate for signing via - /// the Shared Key Lite authentication scheme for the Table service. - /// - /// Authentication for the Windows Azure Storage Services - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Canonicalizer", Justification = "Reviewed: Canonicalizer can be used as an identifier name.")] - public sealed class SharedKeyLiteTableCanonicalizer : ICanonicalizer - { - private const string SharedKeyLiteAuthorizationScheme = "SharedKeyLite"; - private const int ExpectedCanonicalizedStringLength = 150; - - private static SharedKeyLiteTableCanonicalizer instance = new SharedKeyLiteTableCanonicalizer(); - - /// - /// Gets a static instance of the object. - /// - /// The static instance of the class. - /// Authentication for the Windows Azure Storage Services - public static SharedKeyLiteTableCanonicalizer Instance - { - get - { - return SharedKeyLiteTableCanonicalizer.instance; - } - } - - private SharedKeyLiteTableCanonicalizer() - { - } - - /// - /// Gets the authorization scheme used for canonicalization. - /// - /// The authorization scheme used for canonicalization. - /// Authentication for the Windows Azure Storage Services - public string AuthorizationScheme - { - get - { - return SharedKeyLiteAuthorizationScheme; - } - } - - /// - /// Converts the specified HTTP request data into a standard form appropriate for signing. - /// - /// The HTTP request that needs to be signed. - /// The name of the storage account that the HTTP request will access. - /// The canonicalized string containing the HTTP request data in a standard form appropriate for signing. - /// Authentication for the Windows Azure Storage Services - public string CanonicalizeHttpRequest(HttpWebRequest request, string accountName) - { - CommonUtility.AssertNotNull("request", request); - - // Add the x-ms-date or Date HTTP header - string dateHeaderValue = AuthenticationUtility.GetPreferredDateHeaderValue(request); - CanonicalizedString canonicalizedString = new CanonicalizedString(dateHeaderValue, ExpectedCanonicalizedStringLength); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyTableCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyTableCanonicalizer.cs deleted file mode 100644 index f14c8894699b3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Auth/SharedKeyTableCanonicalizer.cs +++ /dev/null @@ -1,93 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System.Net; - - /// - /// Represents a canonicalizer that converts HTTP request data into a standard form appropriate for signing via - /// the Shared Key authentication scheme for the Table service. - /// - /// Authentication for the Windows Azure Storage Services - public sealed class SharedKeyTableCanonicalizer : ICanonicalizer - { - private const string SharedKeyAuthorizationScheme = "SharedKey"; - private const int ExpectedCanonicalizedStringLength = 200; - - private static SharedKeyTableCanonicalizer instance = new SharedKeyTableCanonicalizer(); - - /// - /// Gets a static instance of the object. - /// - /// The static instance of the class. - /// Authentication for the Windows Azure Storage Services - public static SharedKeyTableCanonicalizer Instance - { - get - { - return SharedKeyTableCanonicalizer.instance; - } - } - - private SharedKeyTableCanonicalizer() - { - } - - /// - /// Gets the authorization scheme used for canonicalization. - /// - /// The authorization scheme used for canonicalization. - /// Authentication for the Windows Azure Storage Services - public string AuthorizationScheme - { - get - { - return SharedKeyAuthorizationScheme; - } - } - - /// - /// Converts the specified HTTP request data into a standard form appropriate for signing. - /// - /// The HTTP request that needs to be signed. - /// The name of the storage account that the HTTP request will access. - /// The canonicalized string containing the HTTP request data in a standard form appropriate for signing. - /// Authentication for the Windows Azure Storage Services - public string CanonicalizeHttpRequest(HttpWebRequest request, string accountName) - { - CommonUtility.AssertNotNull("request", request); - - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method, ExpectedCanonicalizedStringLength); - - // Add the Content-* HTTP headers. Empty values are allowed. - canonicalizedString.AppendCanonicalizedElement(request.Headers[HttpRequestHeader.ContentMd5]); - canonicalizedString.AppendCanonicalizedElement(request.ContentType); - - // Add the Date HTTP header (or the x-ms-date header if it is being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request, true); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/Executor.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/Executor.cs deleted file mode 100644 index e6df272c5beb4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/Executor.cs +++ /dev/null @@ -1,818 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - using System.Threading; - - internal class Executor : ExecutorBase - { - #region Async - - #region Begin / End - // Cancellation will be handled by a flag in the return type ( CancellationToken in .net4+ ) - public static ICancellableAsyncResult BeginExecuteAsync(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext, AsyncCallback callback, object asyncState) - { - // Note all code below will reference state, not params directly, this will allow common code with async executor - ExecutionState executionState = new ExecutionState(cmd, policy, operationContext, callback, asyncState); - Executor.InitRequest(executionState); - return executionState; - } - - public static T EndExecuteAsync(IAsyncResult result) - { - CommonUtility.AssertNotNull("result", result); - - ExecutionState executionState = (ExecutionState)result; - - executionState.End(); - - // Clear references - executionState.RestCMD.SendStream = null; - executionState.RestCMD.DestinationStream = null; - - if (executionState.ExceptionRef != null) - { - throw executionState.ExceptionRef; - } - - return executionState.Result; - } - - #endregion - - #region Steps 0 - 4 Setup Request - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - public static void InitRequest(ExecutionState executionState) - { - try - { - executionState.Init(); - - // 0. Begin Request - Executor.StartRequestAttempt(executionState); - - // Steps 1 - 4 - Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestAsync, executionState.Cmd.Uri); - Executor.ProcessStartOfRequest(executionState); - - if (Executor.CheckTimeout(executionState, false)) - { - Executor.EndOperation(executionState); - return; - } - - lock (executionState.CancellationLockerObject) - { - if (Executor.CheckCancellation(executionState)) - { - Executor.EndOperation(executionState); - return; - } - - // 5. potentially upload data - if (executionState.RestCMD.SendStream != null) - { - Executor.BeginGetRequestStream(executionState); - } - else - { - Executor.BeginGetResponse(executionState); - } - } - } - catch (Exception ex) - { - Logger.LogError(executionState.OperationContext, SR.TraceInitRequestError, ex.Message); - - // Store exception and invoke callback here. All operations in this try would be non-retryable by default - StorageException storageEx = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - storageEx.IsRetryable = false; - executionState.ExceptionRef = storageEx; - executionState.OnComplete(); - } - } - #endregion - - #region Step 5 Get Request Stream & upload - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void BeginGetRequestStream(ExecutionState executionState) - { - executionState.CurrentOperation = ExecutorOperation.BeginGetRequestStream; - Logger.LogInformational(executionState.OperationContext, SR.TracePrepareUpload); - - try - { - APMWithTimeout.RunWithTimeout( - executionState.Req.BeginGetRequestStream, - Executor.EndGetRequestStream, - Executor.AbortRequest, - executionState, - executionState.RemainingTimeout); - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TracePrepareUploadError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - Executor.EndOperation(executionState); - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void EndGetRequestStream(IAsyncResult getRequestStreamResult) - { - ExecutionState executionState = (ExecutionState)getRequestStreamResult.AsyncState; - executionState.CurrentOperation = ExecutorOperation.EndGetRequestStream; - - try - { - executionState.UpdateCompletedSynchronously(getRequestStreamResult.CompletedSynchronously); - - executionState.ReqStream = executionState.Req.EndGetRequestStream(getRequestStreamResult); - - executionState.CurrentOperation = ExecutorOperation.BeginUploadRequest; - Logger.LogInformational(executionState.OperationContext, SR.TraceUpload); - MultiBufferMemoryStream multiBufferMemoryStream = executionState.RestCMD.SendStream as MultiBufferMemoryStream; - if (multiBufferMemoryStream != null && !executionState.RestCMD.SendStreamLength.HasValue) - { - multiBufferMemoryStream.BeginFastCopyTo(executionState.ReqStream, executionState.OperationExpiryTime, EndFastCopyTo, executionState); - } - else - { - // don't calculate md5 here as we should have already set this for auth purposes - executionState.RestCMD.SendStream.WriteToAsync(executionState.ReqStream, executionState.RestCMD.SendStreamLength, null /* maxLength */, false, executionState, null /* streamCopyState */, EndSendStreamCopy); - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceUploadError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - Executor.EndOperation(executionState); - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private static void EndFastCopyTo(IAsyncResult fastCopyToResult) - { - ExecutionState executionState = (ExecutionState)fastCopyToResult.AsyncState; - - try - { - executionState.UpdateCompletedSynchronously(fastCopyToResult.CompletedSynchronously); - - MultiBufferMemoryStream multiBufferMemoryStream = (MultiBufferMemoryStream)executionState.RestCMD.SendStream; - multiBufferMemoryStream.EndFastCopyTo(fastCopyToResult); - - Executor.EndSendStreamCopy(executionState); - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceUploadError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - Executor.EndOperation(executionState); - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void EndSendStreamCopy(ExecutionState executionState) - { - executionState.CurrentOperation = ExecutorOperation.EndUploadRequest; - - lock (executionState.CancellationLockerObject) - { - Executor.CheckCancellation(executionState); - - if (executionState.ExceptionRef != null) - { - try - { - executionState.Req.Abort(); - } - catch (Exception) - { - // No op - } - - Executor.EndOperation(executionState); - } - else - { - try - { - executionState.ReqStream.Flush(); - executionState.ReqStream.Dispose(); - executionState.ReqStream = null; - } - catch (Exception) - { - // If we could not flush/dispose the request stream properly, - // BeginGetResponse will fail with a more meaningful error anyway. - } - - Executor.BeginGetResponse(executionState); - } - } - } - #endregion - - #region Steps 6-8 Get Response & Potentially Send - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void BeginGetResponse(ExecutionState executionState) - { - executionState.CurrentOperation = ExecutorOperation.BeginGetResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceGetResponse); - - try - { - APMWithTimeout.RunWithTimeout( - executionState.Req.BeginGetResponse, - Executor.EndGetResponse, - Executor.AbortRequest, - executionState, - executionState.RemainingTimeout); - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - Executor.EndOperation(executionState); - } - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void EndGetResponse(IAsyncResult getResponseResult) - { - ExecutionState executionState = (ExecutionState)getResponseResult.AsyncState; - executionState.CurrentOperation = ExecutorOperation.EndGetResponse; - - try - { - executionState.UpdateCompletedSynchronously(getResponseResult.CompletedSynchronously); - - try - { - executionState.Resp = executionState.Req.EndGetResponse(getResponseResult) as HttpWebResponse; - } - catch (WebException ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); - executionState.Resp = (HttpWebResponse)ex.Response; - - if (ex.Status == WebExceptionStatus.Timeout || executionState.ReqTimedOut) - { - throw new TimeoutException(); - } - - if (executionState.Resp == null) - { - throw; - } - else - { - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - Executor.FireResponseReceived(executionState); - - // 7. Do Response parsing (headers etc, no stream available here) - if (executionState.RestCMD.PreProcessResponse != null) - { - executionState.CurrentOperation = ExecutorOperation.PreProcess; - executionState.Result = executionState.RestCMD.PreProcessResponse(executionState.RestCMD, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); - - // clear exception - executionState.ExceptionRef = null; - Logger.LogInformational(executionState.OperationContext, SR.TracePreProcessDone); - } - - Executor.CheckCancellation(executionState); - - // 8. (Potentially reads stream from server) - if (executionState.ExceptionRef == null) - { - executionState.CurrentOperation = ExecutorOperation.GetResponseStream; - executionState.RestCMD.ResponseStream = executionState.Resp.GetResponseStream(); - - if (!executionState.RestCMD.RetrieveResponseStream) - { - executionState.RestCMD.DestinationStream = Stream.Null; - } - - if (executionState.RestCMD.DestinationStream != null) - { - if (executionState.RestCMD.StreamCopyState == null) - { - executionState.RestCMD.StreamCopyState = new StreamDescriptor(); - } - - executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceDownload); - executionState.RestCMD.ResponseStream.WriteToAsync(executionState.RestCMD.DestinationStream, null /* copyLength */, null /* maxLength */, executionState.RestCMD.CalculateMd5ForResponseStream, executionState, executionState.RestCMD.StreamCopyState, EndResponseStreamCopy); - } - else - { - // Dont want to copy stream, just want to consume it so end - Executor.EndOperation(executionState); - } - } - else - { - // End - Executor.EndOperation(executionState); - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TracePreProcessError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - Executor.EndOperation(executionState); - } - } - - private static void EndResponseStreamCopy(ExecutionState executionState) - { - try - { - if (executionState.RestCMD.ResponseStream != null) - { - executionState.RestCMD.ResponseStream.Dispose(); - executionState.RestCMD.ResponseStream = null; - } - } - catch (Exception) - { - // no-op, because HttpWebResponse.Close should take care of it - } - - executionState.CurrentOperation = ExecutorOperation.EndDownloadResponse; - Executor.EndOperation(executionState); - } - #endregion - - #region Step 9 - Parse Response - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private static void EndOperation(ExecutionState executionState) - { - Executor.FinishRequestAttempt(executionState); - - lock (executionState.CancellationLockerObject) - { - try - { - // If an operation has been canceled of timed out this should overwrite any exception - Executor.CheckCancellation(executionState); - Executor.CheckTimeout(executionState, true); - - // Success - if (executionState.ExceptionRef == null) - { - // Step 9 - This will not be called if an exception is raised during stream copying - Executor.ProcessEndOfRequest(executionState); - executionState.OnComplete(); - return; - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TracePostProcessError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - finally - { - try - { - if (executionState.ReqStream != null) - { - executionState.ReqStream.Dispose(); - executionState.ReqStream = null; - } - - if (executionState.Resp != null) - { - executionState.Resp.Close(); - executionState.Resp = null; - } - } - catch (Exception) - { - // no op - } - } - } - - // Handle Retry - try - { - StorageException translatedException = StorageException.TranslateException(executionState.ExceptionRef, executionState.Cmd.CurrentResult); - executionState.ExceptionRef = translatedException; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); - - bool shouldRetry = false; - TimeSpan delay = TimeSpan.Zero; - if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) - { - shouldRetry = executionState.RetryPolicy.ShouldRetry( - executionState.RetryCount++, - executionState.Cmd.CurrentResult.HttpStatusCode, - executionState.ExceptionRef, - out delay, - executionState.OperationContext); - - if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) - { - delay = Constants.MaximumRetryBackoff; - } - } - - if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); - - // No Retry - executionState.OnComplete(); - } - else - { - if (executionState.Cmd.RecoveryAction != null) - { - // I.E. Rewind stream etc. - executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); - } - - if (delay > TimeSpan.Zero) - { - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryDelay, (int)delay.TotalMilliseconds); - - executionState.UpdateCompletedSynchronously(false); - if (executionState.BackoffTimer == null) - { - executionState.BackoffTimer = new Timer( - Executor.RetryRequest, - executionState, - (int)delay.TotalMilliseconds, - Timeout.Infinite); - } - else - { - executionState.BackoffTimer.Change((int)delay.TotalMilliseconds, Timeout.Infinite); - } - - executionState.CancelDelegate = () => - { - // Disabling the timer here, but there is still a scenario where the user calls cancel after - // the timer starts the next retry but before it sets the CancelDelegate back to null. However, even - // if that happens, next retry will start and then stop immediately because of the cancelled flag. - Timer backoffTimer = executionState.BackoffTimer; - if (backoffTimer != null) - { - executionState.BackoffTimer = null; - backoffTimer.Dispose(); - } - - Logger.LogWarning(executionState.OperationContext, SR.TraceAbortRetry); - Executor.CheckCancellation(executionState); - executionState.OnComplete(); - }; - } - else - { - // Start next request immediately - Executor.RetryRequest(executionState); - } - } - } - catch (Exception ex) - { - // Catch all ( i.e. users retry policy throws etc.) - Logger.LogWarning(executionState.OperationContext, SR.TraceRetryError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - executionState.OnComplete(); - } - } - - private static void RetryRequest(object state) - { - ExecutionState executionState = (ExecutionState)state; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - Executor.InitRequest(executionState); - } - #endregion - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private static void AbortRequest(object state) - { - ExecutionState executionState = (ExecutionState)state; - Logger.LogInformational(executionState.OperationContext, SR.TraceAbort); - - try - { - executionState.ReqTimedOut = true; - executionState.Req.Abort(); - } - catch (Exception ex) - { - Logger.LogError(executionState.OperationContext, SR.TraceAbortError, ex.Message); - } - } - #endregion - - #region Sync -#if SYNC - public static T ExecuteSync(StorageCommandBase cmd, IRetryPolicy policy, OperationContext operationContext) - { - // Note all code below will reference state, not params directly, this will allow common code with async executor - using (ExecutionState executionState = new ExecutionState(cmd, policy, operationContext)) - { - bool shouldRetry = false; - TimeSpan delay = TimeSpan.Zero; - - do - { - try - { - executionState.Init(); - - // 0. Begin Request - Executor.StartRequestAttempt(executionState); - - // Steps 1-4 - Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestSync, cmd.Uri); - Executor.ProcessStartOfRequest(executionState); - - Executor.CheckTimeout(executionState, true); - } - catch (Exception ex) - { - Logger.LogError(executionState.OperationContext, SR.TraceInitRequestError, ex.Message); - - // Store exception and throw here. All operations in this try would be non-retryable by default - StorageException storageEx = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - storageEx.IsRetryable = false; - executionState.ExceptionRef = storageEx; - throw executionState.ExceptionRef; - } - - // Enter Retryable Section of execution - try - { - // 5. potentially upload data - if (executionState.RestCMD.SendStream != null) - { - executionState.CurrentOperation = ExecutorOperation.BeginGetRequestStream; - Logger.LogInformational(executionState.OperationContext, SR.TracePrepareUpload); - executionState.Req.Timeout = (int)executionState.RemainingTimeout.TotalMilliseconds; - executionState.ReqStream = executionState.Req.GetRequestStream(); - - executionState.CurrentOperation = ExecutorOperation.BeginUploadRequest; - Logger.LogInformational(executionState.OperationContext, SR.TraceUpload); - MultiBufferMemoryStream multiBufferMemoryStream = executionState.RestCMD.SendStream as MultiBufferMemoryStream; - - try - { - if (multiBufferMemoryStream != null && !executionState.RestCMD.SendStreamLength.HasValue) - { - multiBufferMemoryStream.FastCopyTo(executionState.ReqStream, executionState.OperationExpiryTime); - } - else - { - // don't calculate md5 here as we should have already set this for auth purposes - executionState.RestCMD.SendStream.WriteToSync(executionState.ReqStream, executionState.RestCMD.SendStreamLength, null /* maxLength */, false, true, executionState, null /* streamCopyState */); - } - - executionState.ReqStream.Flush(); - executionState.ReqStream.Dispose(); - executionState.ReqStream = null; - } - catch (Exception) - { - executionState.Req.Abort(); - throw; - } - } - - // 6. Get response - try - { - executionState.CurrentOperation = ExecutorOperation.BeginGetResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceGetResponse); - executionState.Req.Timeout = (int)executionState.RemainingTimeout.TotalMilliseconds; - executionState.Resp = (HttpWebResponse)executionState.Req.GetResponse(); - executionState.CurrentOperation = ExecutorOperation.EndGetResponse; - } - catch (WebException ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); - executionState.Resp = (HttpWebResponse)ex.Response; - - if (ex.Status == WebExceptionStatus.Timeout || executionState.ReqTimedOut) - { - throw new TimeoutException(); - } - - if (executionState.Resp == null) - { - throw; - } - else - { - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - } - - // Response - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - Executor.FireResponseReceived(executionState); - - // 7. Do Response parsing (headers etc, no stream available here) - if (executionState.RestCMD.PreProcessResponse != null) - { - executionState.CurrentOperation = ExecutorOperation.PreProcess; - executionState.Result = executionState.RestCMD.PreProcessResponse(executionState.RestCMD, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); - - // clear exception - executionState.ExceptionRef = null; - Logger.LogInformational(executionState.OperationContext, SR.TracePreProcessDone); - } - - // 8. (Potentially reads stream from server) - executionState.CurrentOperation = ExecutorOperation.GetResponseStream; - executionState.RestCMD.ResponseStream = executionState.Resp.GetResponseStream(); - - if (!executionState.RestCMD.RetrieveResponseStream) - { - executionState.RestCMD.DestinationStream = Stream.Null; - } - - if (executionState.RestCMD.DestinationStream != null) - { - if (executionState.RestCMD.StreamCopyState == null) - { - executionState.RestCMD.StreamCopyState = new StreamDescriptor(); - } - - try - { - executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceDownload); - executionState.RestCMD.ResponseStream.WriteToSync(executionState.RestCMD.DestinationStream, null /* copyLength */, null /* maxLength */, executionState.RestCMD.CalculateMd5ForResponseStream, false, executionState, executionState.RestCMD.StreamCopyState); - } - finally - { - executionState.RestCMD.ResponseStream.Dispose(); - executionState.RestCMD.ResponseStream = null; - } - } - - // Step 9 - This will not be called if an exception is raised during stream copying - Executor.ProcessEndOfRequest(executionState); - - Executor.FinishRequestAttempt(executionState); - return executionState.Result; - } - catch (Exception e) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, e.Message); - Executor.FinishRequestAttempt(executionState); - - StorageException translatedException = StorageException.TranslateException(e, executionState.Cmd.CurrentResult); - executionState.ExceptionRef = translatedException; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); - - shouldRetry = false; - if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) - { - shouldRetry = executionState.RetryPolicy.ShouldRetry( - executionState.RetryCount++, - executionState.Cmd.CurrentResult.HttpStatusCode, - executionState.ExceptionRef, - out delay, - executionState.OperationContext); - - if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) - { - delay = Constants.MaximumRetryBackoff; - } - } - } - finally - { - if (executionState.Resp != null) - { - executionState.Resp.Close(); - executionState.Resp = null; - } - } - - if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); - throw executionState.ExceptionRef; - } - else - { - if (executionState.Cmd.RecoveryAction != null) - { - // I.E. Rewind stream etc. - executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); - } - - if (delay > TimeSpan.Zero) - { - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryDelay, (int)delay.TotalMilliseconds); - Thread.Sleep(delay); - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - } - } - while (shouldRetry); - } - - // should never get here, either return, or throw; - throw new NotImplementedException(SR.InternalStorageError); - } -#endif - #endregion - - #region Common - private static void ProcessStartOfRequest(ExecutionState executionState) - { - executionState.CurrentOperation = ExecutorOperation.BeginOperation; - - // 1. Build request - executionState.Req = executionState.RestCMD.BuildRequestDelegate(executionState.Cmd.Uri, executionState.Cmd.Builder, executionState.Cmd.ServerTimeoutInSeconds, executionState.OperationContext); - executionState.CancelDelegate = executionState.Req.Abort; - - // 2. Set Headers - Executor.ApplyUserHeaders(executionState); - if (executionState.RestCMD.SetHeaders != null) - { - executionState.RestCMD.SetHeaders(executionState.Req, executionState.OperationContext); - } - - // Set Content-Length and do minor tweaks - if (executionState.RestCMD.SendStream != null) - { - long streamLength = executionState.RestCMD.SendStreamLength ?? executionState.RestCMD.SendStream.Length - executionState.RestCMD.SendStream.Position; - CommonUtility.ApplyRequestOptimizations(executionState.Req, streamLength); - } - else - { - CommonUtility.ApplyRequestOptimizations(executionState.Req, -1); - } - - // Let the user know we are ready to send - Executor.FireSendingRequest(executionState); - - // 3. Sign Request - if (executionState.RestCMD.SignRequest != null) - { - executionState.RestCMD.SignRequest(executionState.Req, executionState.OperationContext); - } -#if SYNC - // 4. Set timeout (this is actually not honored by asynchronous requests) - executionState.Req.Timeout = (int)executionState.RemainingTimeout.TotalMilliseconds; -#endif - } - - private static void ProcessEndOfRequest(ExecutionState executionState) - { - // 9. Evaluate Response & Parse Results, (Stream potentially available here) - if (executionState.RestCMD.PostProcessResponse != null) - { - executionState.CurrentOperation = ExecutorOperation.PostProcess; - Logger.LogInformational(executionState.OperationContext, SR.TracePostProcess); - executionState.Result = executionState.RestCMD.PostProcessResponse(executionState.RestCMD, executionState.Resp, executionState.OperationContext); - } - - executionState.CurrentOperation = ExecutorOperation.EndOperation; - Logger.LogInformational(executionState.OperationContext, SR.TraceSuccess); - executionState.CancelDelegate = null; - } - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/RecoveryActions.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/RecoveryActions.cs deleted file mode 100644 index ce9cc2d24c964..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/RecoveryActions.cs +++ /dev/null @@ -1,38 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.IO; - - internal static class RecoveryActions - { - internal static void RewindStream(StorageCommandBase cmd, Exception ex, OperationContext ctx) - { - RecoveryActions.SeekStream(cmd, 0); - } - - internal static void SeekStream(StorageCommandBase cmd, long offset) - { - CommonUtility.AssertNotNull("cmd", cmd); - RESTCommand restCMD = (RESTCommand)cmd; - restCMD.SendStream.Seek(offset, SeekOrigin.Begin); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableCommand.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableCommand.cs deleted file mode 100644 index 161d2b8031e6c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableCommand.cs +++ /dev/null @@ -1,35 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ -#if WINDOWS_DESKTOP && ! WINDOWS_PHONE - using Microsoft.WindowsAzure.Storage.Table.DataServices; - using System; - using System.Diagnostics.CodeAnalysis; - - [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed.")] - internal class TableCommand : StorageCommandBase - { - public Func ExecuteFunc; - public Func Begin; - public Func End; - public Func, T> ParseResponse; - public TableServiceContext Context = null; - } -#endif -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableExecutor.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableExecutor.cs deleted file mode 100644 index fc247944a7b85..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Executor/TableExecutor.cs +++ /dev/null @@ -1,506 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ -#if WINDOWS_DESKTOP && ! WINDOWS_PHONE - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.DataServices; - using System; - using System.Diagnostics.CodeAnalysis; - using System.Net; - using System.Threading; - - internal class TableExecutor : ExecutorBase - { - #region Async - - #region Begin / End - // Cancellation is handeld by TableServiceContext - public static ICancellableAsyncResult BeginExecuteAsync(TableCommand cmd, IRetryPolicy policy, OperationContext operationContext, AsyncCallback callback, object asyncState) - { - // Note all code below will reference state, not params directly, this will allow common code with async executor - ExecutionState executionState = new ExecutionState(cmd, policy, operationContext, callback, asyncState); - TableExecutor.AcquireContext(cmd.Context, executionState); - InitRequest(executionState); - return executionState; - } - - public static T EndExecuteAsync(IAsyncResult result) - { - ExecutionState executionState = result as ExecutionState; - - CommonUtility.AssertNotNull("result", executionState); - - executionState.End(); - - TableCommand tableCommandRef = executionState.Cmd as TableCommand; - ReleaseContext(tableCommandRef.Context); - - if (executionState.ExceptionRef != null) - { - throw executionState.ExceptionRef; - } - - return executionState.Result; - } - - #endregion - - #region Setup Request - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - public static void InitRequest(ExecutionState executionState) - { - try - { - executionState.Init(); - - // 0. Begin Request - TableExecutor.StartRequestAttempt(executionState); - - if (TableExecutor.CheckTimeout(executionState, false)) - { - TableExecutor.EndOperation(executionState); - return; - } - - lock (executionState.CancellationLockerObject) - { - if (TableExecutor.CheckCancellation(executionState)) - { - TableExecutor.EndOperation(executionState); - return; - } - - TableCommand tableCommandRef = executionState.Cmd as TableCommand; - - // Execute Call - Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestAsync, tableCommandRef.Context.BaseUri); - tableCommandRef.Begin( - (res) => - { - executionState.UpdateCompletedSynchronously(res.CompletedSynchronously); - INTERMEDIATE_TYPE tResult = default(INTERMEDIATE_TYPE); - - try - { - tResult = tableCommandRef.End(res); - - executionState.Result = tableCommandRef.ParseResponse(tResult, executionState.Cmd.CurrentResult, tableCommandRef); - - // Attempt to populate response headers - if (executionState.Req != null) - { - executionState.Resp = GetResponseForRequest(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - FireResponseReceived(executionState); - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, ex.Message); - - lock (executionState.CancellationLockerObject) - { - if (executionState.CancelRequested) - { - // Ignore DSC exception if request was canceled. - return; - } - } - - // Store exception and invoke callback here. All operations in this try would be non-retryable by default - if (executionState.ExceptionRef == null || !(executionState.ExceptionRef is StorageException)) - { - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - - try - { - // Attempt to populate response headers - if (executionState.Req != null) - { - executionState.Resp = GetResponseForRequest(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - FireResponseReceived(executionState); - } - - executionState.Result = tableCommandRef.ParseResponse(tResult, executionState.Cmd.CurrentResult, tableCommandRef); - - // clear exception - executionState.ExceptionRef = null; - } - catch (Exception parseEx) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, ex.Message); - executionState.ExceptionRef = parseEx; - } - } - finally - { - EndOperation(executionState); - } - }, - null); - - if (tableCommandRef.Context != null) - { - executionState.CancelDelegate = tableCommandRef.Context.InternalCancel; - } - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, ex.Message); - - // Store exception and invoke callback here. All operations in this try would be non-retryable by default - if (executionState.ExceptionRef == null || !(executionState.ExceptionRef is StorageException)) - { - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - - executionState.OnComplete(); - } - } - #endregion - - #region Parse Response - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private static void EndOperation(ExecutionState executionState) - { - TableExecutor.FinishRequestAttempt(executionState); - - lock (executionState.CancellationLockerObject) - { - executionState.CancelDelegate = null; - - TableExecutor.CheckCancellation(executionState); - - // Handle Success - if (executionState.ExceptionRef == null) - { - Logger.LogInformational(executionState.OperationContext, SR.TraceSuccess); - executionState.OnComplete(); - return; - } - } - - // Handle Retry - try - { - StorageException translatedException = StorageException.TranslateException(executionState.ExceptionRef, executionState.Cmd.CurrentResult); - executionState.ExceptionRef = translatedException; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); - - bool shouldRetry = false; - TimeSpan delay = TimeSpan.Zero; - if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) - { - shouldRetry = executionState.RetryPolicy.ShouldRetry( - executionState.RetryCount++, - executionState.Cmd.CurrentResult.HttpStatusCode, - executionState.ExceptionRef, - out delay, - executionState.OperationContext); - - if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) - { - delay = Constants.MaximumRetryBackoff; - } - } - - if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); - - // No Retry - executionState.OnComplete(); - } - else - { - if (executionState.Cmd.RecoveryAction != null) - { - // I.E. Rewind stream etc. - executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); - } - - if (delay > TimeSpan.Zero) - { - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryDelay, (int)delay.TotalMilliseconds); - - executionState.UpdateCompletedSynchronously(false); - if (executionState.BackoffTimer == null) - { - executionState.BackoffTimer = new Timer( - TableExecutor.RetryRequest, - executionState, - (int)delay.TotalMilliseconds, - Timeout.Infinite); - } - else - { - executionState.BackoffTimer.Change((int)delay.TotalMilliseconds, Timeout.Infinite); - } - - executionState.CancelDelegate = () => - { - // Disabling the timer here, but there is still a scenario where the user calls cancel after - // the timer starts the next retry but before it sets the CancelDelegate back to null. However, even - // if that happens, next retry will start and then stop immediately because of the cancelled flag. - Timer backoffTimer = executionState.BackoffTimer; - if (backoffTimer != null) - { - executionState.BackoffTimer = null; - backoffTimer.Dispose(); - } - - Logger.LogWarning(executionState.OperationContext, SR.TraceAbortRetry); - TableExecutor.CheckCancellation(executionState); - executionState.OnComplete(); - }; - } - else - { - // Start Next Request Immediately - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - InitRequest(executionState); - } - } - } - catch (Exception ex) - { - // Catch all ( i.e. users retry policy throws etc.) - Logger.LogWarning(executionState.OperationContext, SR.TraceRetryError, ex.Message); - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - executionState.OnComplete(); - } - } - - private static void RetryRequest(object state) - { - ExecutionState executionState = (ExecutionState)state; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - TableExecutor.InitRequest(executionState); - } - #endregion - - #endregion - - #region Sync - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - public static T ExecuteSync(TableCommand cmd, IRetryPolicy policy, OperationContext operationContext) - { - // Note all code below will reference state, not params directly, this will allow common code with async executor - ExecutionState executionState = new ExecutionState(cmd, policy, operationContext); - TableExecutor.AcquireContext(cmd.Context, executionState); - bool shouldRetry = false; - TimeSpan delay = TimeSpan.Zero; - - try - { - // Enter Retryable Section of execution - do - { - executionState.Init(); - - // 0. Begin Request - TableExecutor.StartRequestAttempt(executionState); - - TableExecutor.CheckTimeout(executionState, true); - - try - { - INTERMEDIATE_TYPE tempResult = default(INTERMEDIATE_TYPE); - - try - { - Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestSync, cmd.Context.BaseUri); - tempResult = cmd.ExecuteFunc(); - - executionState.Result = cmd.ParseResponse(tempResult, executionState.Cmd.CurrentResult, cmd); - - // Attempt to populate response headers - if (executionState.Req != null) - { - executionState.Resp = GetResponseForRequest(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - TableExecutor.FireResponseReceived(executionState); - } - } - catch (Exception ex) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, ex.Message); - - // Store exception and invoke callback here. All operations in this try would be non-retryable by default - if (executionState.ExceptionRef == null || !(executionState.ExceptionRef is StorageException)) - { - executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - } - - // Attempt to populate response headers - if (executionState.Req != null) - { - executionState.Resp = GetResponseForRequest(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - TableExecutor.FireResponseReceived(executionState); - } - - executionState.Result = cmd.ParseResponse(tempResult, executionState.Cmd.CurrentResult, cmd); - - // clear exception - executionState.ExceptionRef = null; - } - - TableExecutor.FinishRequestAttempt(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceSuccess); - return executionState.Result; - } - catch (Exception e) - { - TableExecutor.FinishRequestAttempt(executionState); - - StorageException translatedException = StorageException.TranslateException(e, executionState.Cmd.CurrentResult); - executionState.ExceptionRef = translatedException; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); - - shouldRetry = false; - if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) - { - shouldRetry = executionState.RetryPolicy.ShouldRetry( - executionState.RetryCount++, - executionState.Cmd.CurrentResult.HttpStatusCode, - executionState.ExceptionRef, - out delay, - executionState.OperationContext); - - if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) - { - delay = Constants.MaximumRetryBackoff; - } - } - } - - if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); - throw executionState.ExceptionRef; - } - else - { - if (executionState.Cmd.RecoveryAction != null) - { - // I.E. Rewind stream etc. - executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryDelay, (int)delay.TotalMilliseconds); - if (delay > TimeSpan.Zero) - { - Thread.Sleep(delay); - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - } - } - while (shouldRetry); - - // should never get here, either return, or throw; - throw new NotImplementedException(SR.InternalStorageError); - } - finally - { - ReleaseContext(cmd.Context); - } - } - - #endregion - - #region TableServiceContext Interop - - private static void Context_SendingSignedRequest(ExecutionState executionState, HttpWebRequest req) - { - // Handle multiple astoria transactions per execute - if (executionState.Req != null) - { - executionState.Resp = GetResponseForRequest(executionState); - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - TableExecutor.FireResponseReceived(executionState); - - executionState.Req = null; - - // Finish previous attempt - TableExecutor.FinishRequestAttempt(executionState); - - // on successes for multiple Astoria operations start new request - if ((int)executionState.Resp.StatusCode < 300) - { - // 0. Setup Next RequestResult - TableExecutor.StartRequestAttempt(executionState); - } - - TableExecutor.CheckTimeout(executionState, true); - } - - executionState.Req = req; - - TableExecutor.ApplyUserHeaders(executionState); - TableExecutor.FireSendingRequest(executionState); - } - - [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "TableServiceContext", Justification = "Splitting TableServiceContext can be confusing to the user")] - internal static void AcquireContext(TableServiceContext ctx, ExecutionState executionState) - { - // This is a fail safe against deadlock in case a callback is ever lost etc and the context is not released - if (!ctx.ContextSemaphore.WaitOne(20000)) - { - throw new TimeoutException(SR.ConcurrentOperationsNotSupported); - } - - ctx.SendingSignedRequestAction = (request) => Context_SendingSignedRequest(executionState, request); - } - - internal static void ReleaseContext(TableServiceContext ctx) - { - ctx.SendingSignedRequestAction = null; - ctx.ResetCancellation(); - ctx.ContextSemaphore.Release(); - } - - internal static HttpWebResponse GetResponseForRequest(ExecutionState executionState) - { - try - { - return (HttpWebResponse)executionState.Req.GetResponse(); - } - catch (WebException e) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, e.Message); - return (HttpWebResponse)e.Response; - } - } - #endregion - } -#endif -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Logger.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Logger.cs deleted file mode 100644 index bd59310ac6f1f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Logger.cs +++ /dev/null @@ -1,131 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics; - - internal static partial class Logger - { -#if !WINDOWS_PHONE - private static TraceSource traceSource = new TraceSource(Constants.LogSourceName); - private static volatile bool isClosed = false; -#endif - -#if !WINDOWS_PHONE - static Logger() - { - AppDomain.CurrentDomain.DomainUnload += new EventHandler(Logger.AppDomainUnloadEvent); - AppDomain.CurrentDomain.ProcessExit += new EventHandler(Logger.ProcessExitEvent); - } -#endif - -#if !WINDOWS_PHONE - private static void Close() - { - Logger.isClosed = true; - - TraceSource source = Logger.traceSource; - if (source != null) - { - Logger.traceSource = null; - source.Close(); - } - } - - private static void ProcessExitEvent(object sender, EventArgs e) - { - Logger.Close(); - } - - private static void AppDomainUnloadEvent(object sender, EventArgs e) - { - Logger.Close(); - } -#endif - - internal static void LogError(OperationContext operationContext, string format, params object[] args) - { -#if WINDOWS_PHONE - if (Logger.ShouldLog(LogLevel.Error, operationContext)) - { - Debug.WriteLine(Logger.FormatLine(operationContext, format, args)); - } -#else - if (!Logger.isClosed && - Logger.traceSource.Switch.ShouldTrace(TraceEventType.Error) && - Logger.ShouldLog(LogLevel.Error, operationContext)) - { - Logger.traceSource.TraceEvent(TraceEventType.Error, 1, Logger.FormatLine(operationContext, format, args)); - } -#endif - } - - internal static void LogWarning(OperationContext operationContext, string format, params object[] args) - { -#if WINDOWS_PHONE - if (Logger.ShouldLog(LogLevel.Warning, operationContext)) - { - Debug.WriteLine(Logger.FormatLine(operationContext, format, args)); - } -#else - if (!Logger.isClosed && - Logger.traceSource.Switch.ShouldTrace(TraceEventType.Warning) && - Logger.ShouldLog(LogLevel.Warning, operationContext)) - { - Logger.traceSource.TraceEvent(TraceEventType.Warning, 2, Logger.FormatLine(operationContext, format, args)); - } -#endif - } - - internal static void LogInformational(OperationContext operationContext, string format, params object[] args) - { -#if WINDOWS_PHONE - if (Logger.ShouldLog(LogLevel.Informational, operationContext)) - { - Debug.WriteLine(Logger.FormatLine(operationContext, format, args)); - } -#else - if (!Logger.isClosed && - Logger.traceSource.Switch.ShouldTrace(TraceEventType.Information) && - Logger.ShouldLog(LogLevel.Informational, operationContext)) - { - Logger.traceSource.TraceEvent(TraceEventType.Information, 3, Logger.FormatLine(operationContext, format, args)); - } -#endif - } - - internal static void LogVerbose(OperationContext operationContext, string format, params object[] args) - { -#if WINDOWS_PHONE - if (Logger.ShouldLog(LogLevel.Verbose, operationContext)) - { - Debug.WriteLine(Logger.FormatLine(operationContext, format, args)); - } -#else - if (!Logger.isClosed && - Logger.traceSource.Switch.ShouldTrace(TraceEventType.Verbose) && - Logger.ShouldLog(LogLevel.Verbose, operationContext)) - { - Logger.traceSource.TraceEvent(TraceEventType.Verbose, 4, Logger.FormatLine(operationContext, format, args)); - } -#endif - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/APMWithTimeout.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/APMWithTimeout.cs deleted file mode 100644 index cb5fe367e1cb8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/APMWithTimeout.cs +++ /dev/null @@ -1,122 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Threading; - - /// - /// Helper class to allow an APM Method to be executed with a given timeout in milliseconds - /// - internal sealed class APMWithTimeout : IDisposable - { - public static void RunWithTimeout(Func beginMethod, AsyncCallback callback, TimerCallback timeoutCallback, object state, TimeSpan timeout) - { - CommonUtility.AssertNotNull("beginMethod", beginMethod); - CommonUtility.AssertNotNull("callback", callback); - CommonUtility.AssertNotNull("timeoutCallback", timeoutCallback); - - APMWithTimeout operation = new APMWithTimeout(timeoutCallback); - operation.Begin(beginMethod, callback, state, timeout); - } - - private TimerCallback timeoutCallback; - private RegisteredWaitHandle waitHandle; - private IAsyncResult asyncResult; - private bool disposed; - -#if WINDOWS_PHONE - // Windows Phone does not let us use IAsyncResult.AsyncWaitHandle - // on most APM methods, so we will just use a fake event that - // will never be signaled. That way, we will always timeout, but - // we will check if the asynchronous operation is completed in the - // timeout callback. However, we cannot make this static, as - // RegisterWaitForSingleObject needs a different handle for every call. - private ManualResetEvent fakeEvent = new ManualResetEvent(false); -#endif - - private APMWithTimeout(TimerCallback timeoutCallback) - { - this.timeoutCallback = timeoutCallback; - } - - private void Begin(Func beginMethod, AsyncCallback callback, object state, TimeSpan timeout) - { - this.asyncResult = beginMethod(callback, state); - -#if WINDOWS_PHONE - WaitHandle asyncWaitHandle = this.fakeEvent; -#else - WaitHandle asyncWaitHandle = this.asyncResult.AsyncWaitHandle; -#endif - - this.waitHandle = ThreadPool.RegisterWaitForSingleObject(asyncWaitHandle, this.WaitCallback, state, timeout, true); - if (this.disposed) - { - this.UnregisterWaitHandle(); - } - } - - private void WaitCallback(object state, bool timedOut) - { - try - { - if (timedOut && !this.asyncResult.IsCompleted) - { - TimerCallback callback = this.timeoutCallback; - this.timeoutCallback = null; - - if (callback != null) - { - callback(state); - } - } - } - finally - { - this.Dispose(); - } - } - - private void UnregisterWaitHandle() - { - RegisteredWaitHandle handle = Interlocked.Exchange(ref this.waitHandle, null); - if (handle != null) - { - handle.Unregister(null); - } - } - - public void Dispose() - { - if (!this.disposed) - { - this.disposed = true; - this.UnregisterWaitHandle(); - -#if WINDOWS_PHONE - if (this.fakeEvent != null) - { - this.fakeEvent.Close(); - this.fakeEvent = null; - } -#endif - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncExtensions.cs deleted file mode 100644 index 7daef1212ec95..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncExtensions.cs +++ /dev/null @@ -1,440 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Threading; - using System.Threading.Tasks; - -#if TASK - /// - /// Helper class to convert an APM method to a Task method. - /// - internal static class AsyncExtensions - { - private static CancellationTokenRegistration? RegisterCancellationToken(CancellationToken cancellationToken, out CancellableOperationBase cancellableOperation) - { - if (cancellationToken.CanBeCanceled) - { - cancellableOperation = new CancellableOperationBase(); - return cancellationToken.Register(cancellableOperation.Cancel); - } - - cancellableOperation = null; - return null; - } - - private static void AssignCancellableOperation(CancellableOperationBase cancellableOperation, ICancellableAsyncResult asyncResult, CancellationToken cancellationToken) - { - if (cancellableOperation != null) - { - cancellableOperation.CancelDelegate = asyncResult.Cancel; - - if (cancellationToken.IsCancellationRequested) - { - cancellableOperation.Cancel(); - } - } - } - - private static AsyncCallback CreateCallback(TaskCompletionSource taskCompletionSource, CancellationTokenRegistration? registration, Func endMethod) - { - return ar => - { - try - { - if (registration.HasValue) - { - registration.Value.Dispose(); - } - - TResult result = endMethod(ar); - taskCompletionSource.TrySetResult(result); - } - catch (OperationCanceledException) - { - taskCompletionSource.TrySetCanceled(); - } - catch (StorageException ex) - { - bool operationCanceled = false; - - // Iterate through all inner exceptions to find an OperationCanceledException - for (Exception innerException = ex.InnerException; innerException != null; innerException = innerException.InnerException) - { - if (innerException is OperationCanceledException) - { - operationCanceled = true; - break; - } - } - - if (operationCanceled) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - taskCompletionSource.TrySetException(ex); - } - } - catch (Exception ex) - { - taskCompletionSource.TrySetException(ex); - } - }; - } - - private static AsyncCallback CreateCallbackVoid(TaskCompletionSource taskCompletionSource, CancellationTokenRegistration? registration, Action endMethod) - { - return ar => - { - try - { - if (registration.HasValue) - { - registration.Value.Dispose(); - } - - endMethod(ar); - taskCompletionSource.TrySetResult(null); - } - catch (OperationCanceledException) - { - taskCompletionSource.TrySetCanceled(); - } - catch (StorageException ex) - { - bool operationCanceled = false; - - // Iterate through all inner exceptions to find an OperationCanceledException - for (Exception innerException = ex.InnerException; innerException != null; innerException = innerException.InnerException) - { - if (innerException is OperationCanceledException) - { - operationCanceled = true; - break; - } - } - - if (operationCanceled) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - taskCompletionSource.TrySetException(ex); - } - } - catch (Exception ex) - { - taskCompletionSource.TrySetException(ex); - } - }; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, arg6, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromVoidApm(Func beginMethod, Action endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, arg6, arg7, CreateCallbackVoid(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, arg6, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - - internal static Task TaskFromApm(Func beginMethod, Func endMethod, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, CancellationToken cancellationToken) - { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); - if (cancellationToken.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else - { - CancellableOperationBase cancellableOperation; - CancellationTokenRegistration? registration = RegisterCancellationToken(cancellationToken, out cancellableOperation); - ICancellableAsyncResult result = beginMethod(arg1, arg2, arg3, arg4, arg5, arg6, arg7, CreateCallback(taskCompletionSource, registration, endMethod), null /* state */); - AssignCancellableOperation(cancellableOperation, result, cancellationToken); - } - - return taskCompletionSource.Task; - } - } -#endif -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncSemaphore.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncSemaphore.cs deleted file mode 100644 index 8df657bd03a33..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncSemaphore.cs +++ /dev/null @@ -1,81 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - - /// - /// This class provides asynchronous semaphore functionality (based on Stephen Toub's blog). - /// - [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed - Stephen Toub is a proper noun.")] - internal partial class AsyncSemaphore - { - public delegate void AsyncSemaphoreCallback(bool calledSynchronously); - - private readonly Queue pendingWaits = - new Queue(); - - public bool WaitAsync(AsyncSemaphoreCallback callback) - { - CommonUtility.AssertNotNull("callback", callback); - - lock (this.pendingWaits) - { - if (this.count > 0) - { - this.count--; - } - else - { - this.pendingWaits.Enqueue(callback); - callback = null; - } - } - - if (callback != null) - { - callback(true); - return true; - } - - return false; - } - - public void Release() - { - AsyncSemaphoreCallback callback = null; - lock (this.pendingWaits) - { - if (this.pendingWaits.Count > 0) - { - callback = this.pendingWaits.Dequeue(); - } - else - { - this.count++; - } - } - - if (callback != null) - { - callback(false); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncStreamCopier.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncStreamCopier.cs deleted file mode 100644 index f904716089c70..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/AsyncStreamCopier.cs +++ /dev/null @@ -1,515 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage.Core.Executor; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Threading; - - // Class to copy streams with potentially overlapping read / writes. This uses no waithandle, extra threads, but does contain a single lock - internal class AsyncStreamCopier : IDisposable - { - #region Ctors + Locals - // Note two buffers to do overlapped read and write. Once ReadBuffer is full it will be swapped over to writeBuffer and a write issued. - private byte[] currentReadBuff = null; - private byte[] currentWriteBuff = null; - private volatile int lastReadCount = -1; - private volatile int currentWriteCount = -1; - private StreamDescriptor streamCopyState = null; - - // This variable keeps track of bytes that have already been read from the source stream. - // It should only be modified using Interlocked.Add and read with Interlocked.Read. - private long currentBytesReadFromSource = 0; - - private long? copyLen = null; - private long? maximumLen = null; - - private Stream src = null; - private Stream dest = null; - private Action> completedDel; - - // these locals enforce a lock - private volatile IAsyncResult readRes; - private volatile IAsyncResult writeRes; - private object lockerObj = new object(); - - // Used for cooperative cancellation - private volatile bool cancelRequested = false; - private ExecutionState state = null; - private Action previousCancellationDelegate = null; - - // Used to signal copy completion - private RegisteredWaitHandle waitHandle = null; - private ManualResetEvent completedEvent = new ManualResetEvent(false); - private int completionProcessed = 0; - - /// - /// Creates and initializes a new asynchronous copy operation. - /// - /// The source stream. - /// The destination stream. - /// An ExecutionState used to coordinate copy operation. - /// Size of read and write buffers used to move data. - /// Boolean value indicating whether the MD-5 should be calculated. - /// An object that represents the state for the current operation. - public AsyncStreamCopier(Stream src, Stream dest, ExecutionState state, int buffSize, bool calculateMd5, StreamDescriptor streamCopyState) - { - this.src = src; - this.dest = dest; - this.state = state; - this.currentReadBuff = new byte[buffSize]; - this.currentWriteBuff = new byte[buffSize]; - - this.streamCopyState = streamCopyState; - - if (streamCopyState != null && calculateMd5 && streamCopyState.Md5HashRef == null) - { - streamCopyState.Md5HashRef = new MD5Wrapper(); - } - } - #endregion - - #region Publics - - /// - /// Begins a stream copy operation. - /// - /// Callback delegate - /// Number of bytes to copy from source stream to destination stream. Cannot be passed with a value for maxLength. - /// Maximum length of the source stream. Cannot be passed with a value for copyLength. - public void StartCopyStream(Action> completedDelegate, long? copyLength, long? maxLength) - { - if (copyLength.HasValue && maxLength.HasValue) - { - throw new ArgumentException(SR.StreamLengthMismatch); - } - - if (this.src.CanSeek && maxLength.HasValue && this.src.Length - this.src.Position > maxLength) - { - throw new InvalidOperationException(SR.StreamLengthError); - } - - if (this.src.CanSeek && copyLength.HasValue && this.src.Length - this.src.Position < copyLength) - { - throw new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - - this.copyLen = copyLength; - this.maximumLen = maxLength; - this.completedDel = completedDelegate; - - // If there is a max time specified start timeout timer. - if (this.state.OperationExpiryTime.HasValue) - { - this.waitHandle = ThreadPool.RegisterWaitForSingleObject( - this.completedEvent, - AsyncStreamCopier.MaximumCopyTimeCallback, - this.state, - this.state.RemainingTimeout, - true); - } - - lock (this.state.CancellationLockerObject) - { - this.previousCancellationDelegate = this.state.CancelDelegate; - this.state.CancelDelegate = this.Abort; - } - - // Start first read - this.EndOpWithCatch(null); - } - - /// - /// Aborts an ongoing copy operation. - /// - public void Abort() - { - this.cancelRequested = true; - AsyncStreamCopier.ForceAbort(this.state, false); - } - - /// - /// Cleans up references. To end a copy operation, use Abort(). - /// - public void Dispose() - { - if (this.waitHandle != null) - { - this.waitHandle.Unregister(null); - this.waitHandle = null; - } - - if (this.completedEvent != null) - { - this.completedEvent.Close(); - this.completedEvent = null; - } - - this.state = null; - } - #endregion - - #region Privates - /// - /// Synchronizes Read and Write operations, and handles exceptions. - /// - /// Read/Write operation or null if first run. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool thread.")] - private void EndOpWithCatch(IAsyncResult res) - { - // If the last op complete synchronously then ignore this callback as its caller will process next op - if (res != null && res.CompletedSynchronously) - { - return; - } - - // Begins the next operation and stores any exceptions which occur - lock (this.lockerObj) - { - try - { - this.EndOperation(res); - } - catch (Exception ex) - { - if (this.state.ReqTimedOut) - { - this.state.ExceptionRef = Exceptions.GenerateTimeoutException(this.state.Cmd != null ? this.state.Cmd.CurrentResult : null, ex); - } - else if (this.cancelRequested) - { - this.state.ExceptionRef = Exceptions.GenerateCancellationException(this.state.Cmd != null ? this.state.Cmd.CurrentResult : null, ex); - } - else - { - this.state.ExceptionRef = ex; - } - - // if there is an outstanding read/write let it signal completion since we populated the exception. - if (this.readRes == null && this.writeRes == null) - { - this.SignalCompletion(); - } - } - } - } - - /// - /// Helper method for EndOpWithCatch(IAsyncResult). Begins/Ends Read and Write Stream operations. - /// Should only be called by EndOpWithCatch(IAsyncResult) since it assumes we are inside the lock. - /// - /// Read/Write operation or null if first run. - private void EndOperation(IAsyncResult res) - { - // Check who made this callback - if (res != null) - { - // true is read, false is write - if ((bool)res.AsyncState) - { - // Read callback - this.ProcessEndRead(); - } - else - { - // Write callback - this.ProcessEndWrite(); - } - } - - // While data is remaining and there are no scheduled operations, schedule next write and read - while (!this.ReachedEndOfSrc() && this.readRes == null && this.writeRes == null) - { - // Check if copying should halt - if (!this.ShouldDispatchNextOperation()) - { - this.SignalCompletion(); - return; - } - - // If read buffer contains unwritten data, swap buffers and set currentWriteCount - if (this.ConsumeReadBuffer() > 0) - { - // Schedule write operation from the last read - this.writeRes = this.dest.BeginWrite(this.currentWriteBuff, 0, this.currentWriteCount, this.EndOpWithCatch, false /* write */); - - // If this write completes synchronously, end it here to avoid stack overflow. - if (this.writeRes.CompletedSynchronously) - { - this.ProcessEndWrite(); - } - } - - // If data needs to be read. - int readCount = this.NextReadLength(); - if (readCount != 0) - { - // Schedule read operation - this.readRes = this.src.BeginRead(this.currentReadBuff, 0, readCount, this.EndOpWithCatch, true /* read */); - - // If this read completes synchronously, end it here to avoid stack overflow. - if (this.readRes.CompletedSynchronously) - { - this.ProcessEndRead(); - } - } - else - { - // User requested read end here. Signal end of source. - this.lastReadCount = 0; - } - } - - // If nothing more needs to be read and no write operation is scheduled, we are finished. - if (this.ReachedEndOfSrc() && this.writeRes == null) - { - if (this.state.ExceptionRef == null && this.copyLen.HasValue && this.NextReadLength() != 0) - { - this.state.ExceptionRef = new ArgumentOutOfRangeException("copyLength", SR.StreamLengthShortError); - } - - this.SignalCompletion(); - } - } - - /// - /// Callback for timeout timer. Aborts the AsyncStreamCopier operation if a timeout occurs. - /// - /// Callback state. - /// True if the timer has timed out, false otherwise. - private static void MaximumCopyTimeCallback(object state, bool timedOut) - { - if (timedOut) - { - ExecutionState executionState = (ExecutionState)state; - AsyncStreamCopier.ForceAbort(executionState, true); - } - } - - /// - /// Aborts the AsyncStreamCopier operation. - /// - /// An object that stores state of the operation. - /// True if aborted due to a time out, or false for a general cancellation. - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private static void ForceAbort(ExecutionState executionState, bool timedOut) - { - if (executionState.Req != null) - { - try - { - executionState.ReqTimedOut = timedOut; - executionState.Req.Abort(); - } - catch (Exception) - { - // no op - } - } - - executionState.ExceptionRef = timedOut ? - Exceptions.GenerateTimeoutException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null) : - Exceptions.GenerateCancellationException(executionState.Cmd != null ? executionState.Cmd.CurrentResult : null, null); - } - - /// - /// Terminates and cleans up the AsyncStreamCopier. - /// - private void SignalCompletion() - { - // If already completed return - if (Interlocked.CompareExchange(ref this.completionProcessed, 1, 0) == 0) - { - this.completedEvent.Set(); - this.ProcessCompletion(); - } - } - - /// - /// Helper method for this.SignalCompletion() - /// Should only be called by this.SignalCompletion() - /// - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Reviewed.")] - private void ProcessCompletion() - { - // Re hookup cancellation delegate - this.state.CancelDelegate = this.previousCancellationDelegate; - - // clear references - this.src = null; - this.dest = null; - this.currentReadBuff = null; - this.currentWriteBuff = null; - - if (this.state.ExceptionRef == null && - this.streamCopyState != null && - this.streamCopyState.Md5HashRef != null) - { - try - { - this.streamCopyState.Md5 = this.streamCopyState.Md5HashRef.ComputeHash(); - } - catch (Exception) - { - // no op - } - finally - { - this.streamCopyState.Md5HashRef = null; - } - } - - // invoke the caller's callback - Action> callback = this.completedDel; - this.completedDel = null; - if (callback != null) - { - try - { - callback(this.state); - } - catch (Exception ex) - { - this.state.ExceptionRef = ex; - } - } - - // and finally clear the reference to the state - this.Dispose(); - } - - /// - /// Determines whether the next operation should begin or halt due to an exception or cancellation. - /// - /// True to continue, false to halt. - private bool ShouldDispatchNextOperation() - { - if (this.maximumLen.HasValue && Interlocked.Read(ref this.currentBytesReadFromSource) > this.maximumLen) - { - this.state.ExceptionRef = new InvalidOperationException(SR.StreamLengthError); - } - else if (this.state.OperationExpiryTime.HasValue && DateTime.Now >= this.state.OperationExpiryTime.Value) - { - this.state.ExceptionRef = Exceptions.GenerateTimeoutException(this.state.Cmd != null ? this.state.Cmd.CurrentResult : null, null); - } - else if (this.state.CancelRequested) - { - this.state.ExceptionRef = Exceptions.GenerateCancellationException(this.state.Cmd != null ? this.state.Cmd.CurrentResult : null, null); - } - - // note cancellation will new up a exception and store it, so this will be not null; - // continue if no exceptions so far - return !this.cancelRequested && this.state.ExceptionRef == null; - } - - /// - /// Waits for a read operation to end and updates the AsyncStreamCopier state. - /// - private void ProcessEndRead() - { - IAsyncResult lastReadRes = this.readRes; - this.readRes = null; - this.lastReadCount = this.src.EndRead(lastReadRes); - Interlocked.Add(ref this.currentBytesReadFromSource, this.lastReadCount); - this.state.UpdateCompletedSynchronously(lastReadRes.CompletedSynchronously); - } - - /// - /// Waits for a write operation to end and updates the AsyncStreamCopier state. - /// - private void ProcessEndWrite() - { - IAsyncResult lastWriteRes = this.writeRes; - this.writeRes = null; - this.dest.EndWrite(lastWriteRes); - - this.state.UpdateCompletedSynchronously(lastWriteRes.CompletedSynchronously); - - if (this.streamCopyState != null) - { - this.streamCopyState.Length += this.currentWriteCount; - - if (this.streamCopyState.Md5HashRef != null) - { - this.streamCopyState.Md5HashRef.UpdateHash(this.currentWriteBuff, 0, this.currentWriteCount); - } - } - } - - /// - /// If a read operation has completed with data, swaps the read/write buffers and resets their corresponding counts. - /// This must be called inside a lock as it could lead to undefined behavior if multiple unsynchronized callers simultaneously called in. - /// - /// Number of bytes to write, or negative if no read operation has completed. - private int ConsumeReadBuffer() - { - if (!this.ReadBufferFull()) - { - return this.lastReadCount; - } - - this.currentWriteCount = this.lastReadCount; - this.lastReadCount = -1; - - // The buffer swap sa ves us a memcopy of the data in readBuff. - byte[] tempBuff = null; - tempBuff = this.currentReadBuff; - this.currentReadBuff = this.currentWriteBuff; - this.currentWriteBuff = tempBuff; - - return this.currentWriteCount; - } - - /// - /// Determines the number of bytes that should be read from the source in the next BeginRead operation. - /// Should only be called when no outstanding read operations exist. - /// - /// Number of bytes to read. - private int NextReadLength() - { - if (this.copyLen.HasValue) - { - long bytesRemaining = this.copyLen.Value - Interlocked.Read(ref this.currentBytesReadFromSource); - return (int)Math.Min(bytesRemaining, this.currentReadBuff.Length); - } - - return this.currentReadBuff.Length; - } - - /// - /// Determines whether no more data can be read from the source Stream. - /// - /// True if at the end, false otherwise. - private bool ReachedEndOfSrc() - { - return this.lastReadCount == 0; - } - - /// - /// Determines whether the current read buffer contains data ready to be written. - /// - /// True if read buffer is full, false otherwise. - private bool ReadBufferFull() - { - return this.lastReadCount > 0; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/CancellableOperationBase.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/CancellableOperationBase.cs deleted file mode 100644 index 470aa77ec08b3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/CancellableOperationBase.cs +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - - /// - /// Represents an operation that supports cancellation. Used by - /// ICancellableAsyncResult implementations throughout the library. - /// Also used by AsyncExtensions as a bridge between CancellationToken - /// and the ICancellableAsyncResult returned by an APM method call. - /// - internal class CancellableOperationBase - { - private object cancellationLockerObject = new object(); - - internal object CancellationLockerObject - { - get { return this.cancellationLockerObject; } - set { this.cancellationLockerObject = value; } - } - - private volatile bool cancelRequested = false; - - internal bool CancelRequested - { - get { return this.cancelRequested; } - set { this.cancelRequested = value; } - } - - private Action cancelDelegate = null; - - internal Action CancelDelegate - { - get - { - lock (this.cancellationLockerObject) - { - return this.cancelDelegate; - } - } - - set - { - lock (this.cancellationLockerObject) - { - this.cancelDelegate = value; - } - } - } - - public void Cancel() - { - lock (this.cancellationLockerObject) - { - this.cancelRequested = true; - if (this.CancelDelegate != null) - { - this.CancelDelegate(); - this.CancelDelegate = null; - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMD5.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMD5.cs deleted file mode 100644 index 9d6fe2cda71f0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMD5.cs +++ /dev/null @@ -1,178 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ -#if WINDOWS_DESKTOP && ! WINDOWS_PHONE - using System; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Runtime.InteropServices; - using System.Security.Cryptography; - - /// - /// The class is provides the helper functions to do FISMA compliant MD5. - /// - internal sealed class NativeMD5 : MD5 - { - /// - /// Cryptographic service provider. - /// - private const uint ProvRsaFull = 0x00000001; - - /// - /// Access to the private keys is not required and the user interface can be bypassed. - /// - private const uint CryptVerifyContext = 0xF0000000; - - /// - /// ALG_ID value that identifies the hash algorithm to use. - /// - private const uint CalgMD5 = 0x00008003; - - /// - /// The hash value or message hash for the hash object specified by hashHandle. - /// - private const uint HashVal = 0x00000002; - - /// - /// The address to which the function copies a handle to the new hash object. Has to be released by calling the CryptDestroyHash function after we are finished using the hash object. - /// - [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = "We release this handle using CryptDestroyHash")] - private IntPtr hashHandle; - - /// - /// A handle to a CSP created by a call to CryptAcquireContext. - /// - [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = "We release this handle using CryptReleaseContext")] - private IntPtr hashProv; - - /// - /// Whether this object has been torn down or not. - /// - private bool disposed = false; - - /// - /// Initializes a new instance of NativeMD5. - /// - public NativeMD5() - : base() - { - NativeMD5.ValidateReturnCode(NativeMethods.CryptAcquireContextW(out this.hashProv, null, null, ProvRsaFull, CryptVerifyContext)); - this.Initialize(); - } - - /// - /// Finalizes an instance of the NativeMD5 class, unhooking it from all events. - /// - ~NativeMD5() - { - this.Dispose(false); - } - - /// - /// Initializes an implementation of the NativeMD5 class. - /// - public override void Initialize() - { - if (this.hashHandle != IntPtr.Zero) - { - NativeMethods.CryptDestroyHash(this.hashHandle); - this.hashHandle = IntPtr.Zero; - } - - NativeMD5.ValidateReturnCode(NativeMethods.CryptCreateHash(this.hashProv, CalgMD5, IntPtr.Zero, 0, out this.hashHandle)); - } - - /// - /// Routes data written to the object into the hash algorithm for computing the hash. - /// - /// The input to compute the hash code for. - /// The offset into the byte array from which to begin using data. - /// The number of bytes in the byte array to use as data. - protected override void HashCore(byte[] array, int offset, int dataLen) - { - GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); - try - { - IntPtr buffPtr = handle.AddrOfPinnedObject(); - if (offset != 0) - { - buffPtr = IntPtr.Add(buffPtr, offset); - } - - NativeMD5.ValidateReturnCode(NativeMethods.CryptHashData(this.hashHandle, buffPtr, dataLen, 0)); - } - finally - { - handle.Free(); - } - } - - /// - /// Finalizes the hash computation after the last data is processed by the cryptographic stream object. - /// - /// The computed hash code. - protected override byte[] HashFinal() - { - byte[] hashBytes = new byte[16]; - int hashLength = hashBytes.Length; - NativeMD5.ValidateReturnCode(NativeMethods.CryptGetHashParam(this.hashHandle, HashVal, hashBytes, ref hashLength, 0)); - return hashBytes; - } - - /// - /// Releases the unmanaged resources used by the NativeMD5. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool disposing) - { - if (!this.disposed) - { - if (this.hashHandle != IntPtr.Zero) - { - NativeMethods.CryptDestroyHash(this.hashHandle); - this.hashHandle = IntPtr.Zero; - } - - if (this.hashProv != IntPtr.Zero) - { - NativeMethods.CryptReleaseContext(this.hashProv, 0); - this.hashProv = IntPtr.Zero; - } - - this.disposed = true; - } - - base.Dispose(disposing); - } - - /// - /// Validates the status returned by all the crypto functions and throws exception per the return code. - /// - /// The boolean status returned by the crypto functions. - private static void ValidateReturnCode(bool status) - { - if (!status) - { - int error = Marshal.GetLastWin32Error(); - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, SR.CryptoFunctionFailed, error)); - } - } - } -#endif -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMethods.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMethods.cs deleted file mode 100644 index 1a5fc01752e16..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/NativeMethods.cs +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Runtime.InteropServices; - - internal static class NativeMethods - { - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptAcquireContextW( - out IntPtr hashProv, - string pszContainer, - string pszProvider, - uint provType, - uint flags); - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptDestroyHash( - IntPtr hashHandle); - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptReleaseContext( - IntPtr hashProv, - int dwFlags); // Reserved. Must be 0. - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptGetHashParam( - IntPtr hashHandle, - uint param, - byte[] data, - ref int pdwDataLen, - uint flags); - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptCreateHash( - IntPtr hashProv, - uint algId, - IntPtr hashKey, - uint flags, - out IntPtr hashHandle); - - [DllImport("advapi32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CryptHashData( - IntPtr hashHandle, - IntPtr data, - int dataLen, - uint flags); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageAsyncResult.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageAsyncResult.cs deleted file mode 100644 index ab5d5fb45dd84..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageAsyncResult.cs +++ /dev/null @@ -1,79 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using Microsoft.WindowsAzure.Storage; - using System; - using System.Diagnostics; - - /// - /// Represents the async result returned by operations that do not directly - /// call into the Executor. - /// - /// Async operation's result type - internal class StorageAsyncResult : StorageCommandAsyncResult - { - internal T Result { get; set; } - - internal OperationContext OperationContext { get; set; } - - internal IRequestOptions RequestOptions { get; set; } - - internal object OperationState { get; set; } - - internal Exception ExceptionRef { get; private set; } - - /// - /// Initializes a new instance of the StorageAsyncResult class. - /// - /// The callback method to be used on completion. - /// The state for the callback. - internal StorageAsyncResult(AsyncCallback callback, object state) - : base(callback, state) - { - } - - /// - /// Called on completion of the async operation to notify the user - /// - /// Exception that was caught by the caller. - [DebuggerNonUserCode] - internal void OnComplete(Exception exception) - { - // This method should not do anything else than just storing the exception, - // as callers might simply call OnComplete() if there was no exception - // and we do not override that method here. - this.ExceptionRef = exception; - this.OnComplete(); - } - - /// - /// Blocks the calling thread until the async operation is completed and throws - /// any stored exceptions. - /// - [DebuggerNonUserCode] - internal override void End() - { - base.End(); - if (this.ExceptionRef != null) - { - throw this.ExceptionRef; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageCommandAsyncResult.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageCommandAsyncResult.cs deleted file mode 100644 index 04908d668d33e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Core/Util/StorageCommandAsyncResult.cs +++ /dev/null @@ -1,221 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Diagnostics; - using System.Threading; - - /// - /// Represents the async result returned by a storage command. - /// - internal class StorageCommandAsyncResult : CancellableOperationBase, ICancellableAsyncResult, IDisposable - { - /// - /// The callback provided by the user. - /// - private AsyncCallback userCallback; - - /// - /// The state for the callback. - /// - private object userState; - - /// - /// Indicates whether a task is completed. - /// - private bool isCompleted = false; - - /// - /// Indicates whether task completed synchronously. - /// - private bool completedSynchronously = true; - - /// - /// The event for blocking on this task's completion. - /// - private ManualResetEvent asyncWaitEvent; - - [DebuggerNonUserCode] - protected StorageCommandAsyncResult() - { - } - - /// - /// Initializes a new instance of the StorageCommandAsyncResult class. - /// - /// The callback method to be used on completion. - /// The state for the callback. - [DebuggerNonUserCode] - protected StorageCommandAsyncResult(AsyncCallback callback, object state) - { - this.userCallback = callback; - this.userState = state; - } - - /// - /// Gets A user-defined object that contains information about the asynchronous operation. - /// - [DebuggerNonUserCode] - public object AsyncState - { - get { return this.userState; } - } - - /// - /// Gets a System.Threading.WaitHandle that is used to wait for an asynchronous operation to complete. - /// - [DebuggerNonUserCode] - public WaitHandle AsyncWaitHandle - { - get { return this.LazyCreateWaitHandle(); } - } - - /// - /// Gets a value indicating whether the asynchronous operation completed synchronously. - /// - [DebuggerNonUserCode] - public bool CompletedSynchronously - { - get { return this.completedSynchronously && this.isCompleted; } - } - - /// - /// Gets a value indicating whether the asynchronous operation has completed. - /// - [DebuggerNonUserCode] - public bool IsCompleted - { - get { return this.isCompleted; } - } - - /// - /// We implement the dispose only to allow the explicit closing of the event. - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// Set to true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (this.asyncWaitEvent != null) - { - this.asyncWaitEvent.Close(); - this.asyncWaitEvent = null; - } - } - } - - /// - /// Provides the lazy initialization of the WaitHandle (based on Joe Duffy's blog). - /// - /// The WaitHandle to use for waiting on completion. - private WaitHandle LazyCreateWaitHandle() - { - if (this.asyncWaitEvent != null) - { - return this.asyncWaitEvent; - } - - ManualResetEvent newHandle = new ManualResetEvent(false); - if (Interlocked.CompareExchange(ref this.asyncWaitEvent, newHandle, null) != null) - { - // Handle already created. Release the handle we created, it's garbage. - newHandle.Close(); - } - - if (this.isCompleted) - { - // If the result has already completed, we must ensure we return the - // handle in a signaled state. The read of this.isCompleted must never move - // before the read of m_waitHandle earlier; the use of an interlocked - // compare-exchange just above ensures that. And there's a scenario that could - // lead to multiple threads setting the event; that's no problem. - this.asyncWaitEvent.Set(); - } - - return this.asyncWaitEvent; - } - - /// - /// Called on completion of the async operation to notify the user - /// (Based on Joe Duffy's lockless design). - /// - [DebuggerNonUserCode] - internal void OnComplete() - { - // If completed before, return immediately - if (this.isCompleted) - { - return; - } - - // First mark completion - this.isCompleted = true; - - // And then, if the wait handle was created, we need to signal it. Note the - // use of a memory barrier. This is required to ensure the read of m_waitHandle - // never moves before the store of m_isCompleted; otherwise we might encounter a - // scenario that leads us to not signal the handle, leading to a deadlock. We can't - // just do a volatile read of m_waitHandle, because it is possible for an acquire - // load to move before a store release. - Thread.MemoryBarrier(); - if (this.asyncWaitEvent != null) - { - this.asyncWaitEvent.Set(); - } - - if (this.userCallback != null) - { - this.userCallback(this); - } - } - - /// - /// Blocks the calling thread until the async operation is completed. - /// - [DebuggerNonUserCode] - internal virtual void End() - { - if (!this.isCompleted) - { - this.AsyncWaitHandle.WaitOne(); - } - - this.Dispose(); - } - - /// - /// Updates the CompletedSynchronously flag with another asynchronous operation result. - /// - /// Set to true if the last operation was completed synchronously; false if it was completed asynchronously. - [DebuggerNonUserCode] - internal void UpdateCompletedSynchronously(bool lastOperationCompletedSynchronously) - { - this.completedSynchronously = this.completedSynchronously && lastOperationCompletedSynchronously; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.dll b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.dll deleted file mode 100644 index 361348c48effe..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.xml b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.xml deleted file mode 100644 index e7bfb758a3398..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.Edm.xml +++ /dev/null @@ -1,5221 +0,0 @@ - - - - Microsoft.Data.Edm - - - - Enumerates the EDM property concurrency modes. - - - Denotes a property that should be used for optimistic concurrency checks. - - - Denotes a property that should not be used for optimistic concurrency checks. - - - Defines EDM container element types. - - - Represents an element where the container kind is unknown or in error. - - - Represents an element implementing . - - - Represents an element implementing . - - - Contains IsEquivalentTo() extension methods. - - - Returns true if the compared expression is semantically equivalent to this expression. - Equivalence of the two expressions. - Reference to the calling object. - Expression being compared to. - - - Returns true if the compared entity set is semantically equivalent to this entity set. - The equivalence of the entity sets. - Reference to the calling object. - Entity set being compared to. - - - Returns true if the compared function is semantically equivalent to this function. - Equivalence of the two functions. - Reference to the calling object. - Function being compared to. - - - Returns true if the compared function import is semantically equivalent to this function import. - Equivalence of the two function imports. - Reference to the calling object. - Function import being compared to. - - - Returns true if the compared function parameter is semantically equivalent to this function parameter. - Equivalence of the two function parameters. - Reference to the calling object. - Function parameter being compared to. - - - Returns true if the compared property is semantically equivalent to this property. - Equivalence of the two properties. - Reference to the calling object. - Property being compared to. - - - Returns true if the compared type is semantically equivalent to this type. - Equivalence of the two types. - Reference to the calling object. - Type being compared to. - - - Returns true if the compared type is semantically equivalent to this type. - Equivalence of the two types. - Reference to the calling object. - Type being compared to. - - - Enumerates the modes of parameters of EDM functions. - - - Denotes that a parameter with an unknown or error directionality. - - - Denotes that a parameter is used for input. - - - Denotes that a parameter is used for output. - - - Denotes that a parameter is used for input and output. - - - Represents the location of an EDM item. - - - Creates a new instance of the class. - - - Gets a string representation of the location. - A string representation of the location. - - - Enumerates the multiplicities of EDM navigation properties. - - - The Multiplicity of the association end is unknown. - - - The Multiplicity of the association end is zero or one. - - - The Multiplicity of the association end is one. - - - The Multiplicity of the association end is many. - - - Represents a mapping from an EDM navigation property to an entity set. - - - Creates a new navigation target mapping. - The navigation property. - The entity set that the navigation propertion targets. - - - Gets the navigation property. - - - Gets the target entity set. - - - Enumerates the actions EDM can apply on deletes. - - - Takes no action on delete. - - - On delete also delete items on the other end of the association. - - - Enumerates the kinds of EDM primitives. - - - Represents a primitive type of unknown kind. - - - Represents a Binary type. - - - Represents a Boolean type. - - - Represents a Byte type. - - - Represents a DateTime type. - - - Represents a DateTimeOffset type. - - - Represents a Decimal type. - - - Represents a Double type. - - - Represents a Guid type. - - - Represents an Int16 type. - - - Represents an Int32 type. - - - Represents an Int64 type. - - - Represents a SByte type. - - - Represents a Single type. - - - Represents a String type. - - - Represents a Stream type. - - - Represents a Time type. - - - Represents an arbitrary Geography type. - - - Represents a geography Point type. - - - Represents a geography LineString type. - - - Represents a geography Polygon type. - - - Represents a geography GeographyCollection type. - - - Represents a geography MultiPolygon type. - - - Represents a geography MultiLineString type. - - - Represents a geography MultiPoint type. - - - Represents an arbitrary Geometry type. - - - Represents a geometry Point type. - - - Represents a geometry LineString type. - - - Represents a geometry Polygon type. - - - Represents a geometry GeometryCollection type. - - - Represents a geometry MultiPolygon type. - - - Represents a geometry MultiLineString type. - - - Represents a geometry MultiPoint type. - - - Returns true if this type kind represents a temporal type. - - - Returns true if this primitive type kind represents an integer type. - - - Returns true if this type kind represents a spatial type. - - - Defines EDM property types. - - - Represents a property implementing . - - - Represents a property implementing . - - - Represents a property with an unknown or error kind. - - - Defines EDM schema element types. - - - Represents a schema element with unknown or error kind. - - - Represents a schema element implementing . - - - Represents a schema element implementing . - - - Represents a schema element implementing . - - - Represents a schema element implementing - - - Defines EDM term kinds. - - - Represents a term with unknown or error kind. - - - Represents a term implementing . - - - Represents a term implementing . - - - Defines EDM metatypes. - - - Represents a type with an unknown or error kind. - - - Represents a type implementing . - - - Represents a type implementing . - - - Represents a type implementing . - - - Represents a type implementing . - - - Represents a type implementing . - - - Represents a type implementing . - - - Represents a type implementing . - - - Returns true if this type kind represents a structured type. - - - Provides semantics of the predefined EDM types. - - - Returns a reference to this row type definition. - A reference to this row type definition. - Reference to the calling object. - Flag specifying if the referenced type should be nullable. - - - If this reference is of a binary type, this will return a valid binary type reference to the type definition. Otherwise, it will return a bad binary type reference. - A valid binary type reference if the definition of the reference is of a binary type. Otherwise a bad binary type reference. - Reference to the calling object. - - - If this reference is of a collection type, this will return a valid collection type reference to the type definition. Otherwise, it will return a bad collection type reference. - A valid collection type reference if the definition of the reference is of a collection type. Otherwise a bad collection type reference. - Reference to the calling object. - - - If this reference is of a complex type, this will return a valid complex type reference to the type definition. Otherwise, it will return a bad complex type reference. - A valid complex type reference if the definition of the reference is of a complex type. Otherwise a bad complex type reference. - Reference to the calling object. - - - If this reference is of a decimal type, this will return a valid decimal type reference to the type definition. Otherwise, it will return a bad decimal type reference. - A valid decimal type reference if the definition of the reference is of a decimal type. Otherwise a bad decimal type reference. - Reference to the calling object. - - - If this reference is of an entity type, this will return a valid entity type reference to the type definition. Otherwise, it will return a bad entity type reference. - A valid entity type reference if the definition of the reference is of an entity type. Otherwise a bad entity type reference. - Reference to the calling object. - - - If this reference is of an entity reference type, this will return a valid entity reference type reference to the type definition. Otherwise, it will return a bad entity reference type reference. - A valid entity reference type reference if the definition of the reference is of an entity reference type. Otherwise a bad entity reference type reference. - Reference to the calling object. - - - If this reference is of an enumeration type, this will return a valid enumeration type reference to the type definition. Otherwise, it will return a bad enumeration type reference. - A valid enumeration type reference if the definition of the reference is of an enumeration type. Otherwise a bad enumeration type reference. - Reference to the calling object. - - - If this reference is of a primitive type, this will return a valid primitive type reference to the type definition. Otherwise, it will return a bad primitive type reference. - A valid primitive type reference if the definition of the reference is of a primitive type. Otherwise a bad primitive type reference. - Reference to the calling object. - - - If this reference is of a row type, this will return a valid row type reference to the type definition. Otherwise, it will return a bad row type reference. - A valid row type reference if the definition of the reference is of a row type. Otherwise a bad row type reference. - Reference to the calling object. - - - If this reference is of a spatial type, this will return a valid spatial type reference to the type definition. Otherwise, it will return a bad spatial type reference. - A valid spatial type reference if the definition of the reference is of a spatial type. Otherwise a bad spatial type reference. - Reference to the calling object. - - - If this reference is of a string type, this will return a valid string type reference to the type definition. Otherwise, it will return a bad string type reference. - A valid string type reference if the definition of the reference is of a string type. Otherwise a bad string type reference. - Reference to the calling object. - - - If this reference is of a structured type, this will return a valid structured type reference to the type definition. Otherwise, it will return a bad structured type reference. - A valid structured type reference if the definition of the reference is of a structured type. Otherwise a bad structured type reference. - Reference to the calling object. - - - If this reference is of a temporal type, this will return a valid temporal type reference to the type definition. Otherwise, it will return a bad temporal type reference. - A valid temporal type reference if the definition of the reference is of a temporal type. Otherwise a bad temporal type reference. - Reference to the calling object. - - - Determines if the potential base type is in the inheritance hierarchy of the type being tested. - True if and only if the type inherits from the potential base type. - Type to be tested for derivation from the other type. - The potential base type of the type being tested. - - - Returns true if this reference refers to a binary type. - This reference refers to a binary type. - Reference to the calling object. - - - Returns true if this reference refers to a boolean type. - This reference refers to a boolean type. - Reference to the calling object. - - - Returns true if this reference refers to a byte type. - This reference refers to a byte type. - Reference to the calling object. - - - Returns true if this reference refers to a collection. - This reference refers to a collection. - Reference to the calling object. - - - Returns true if this reference refers to a complex type. - This reference refers to a complex type. - Reference to the calling object. - - - Returns true if this reference refers to a DateTime type. - This reference refers to a DateTime type. - Reference to the calling object. - - - Returns true if this reference refers to a DateTimeOffset type. - This reference refers to a DateTimeOffset type. - Reference to the calling object. - - - Returns true if this reference refers to a decimal type. - This reference refers to a decimal type. - Reference to the calling object. - - - Returns true if this reference refers to a double type. - This reference refers to a double type. - Reference to the calling object. - - - Returns true if this reference refers to an entity type. - This reference refers to an entity type. - Reference to the calling object. - - - Returns true if this reference refers to an entity type. - This reference refers to an entity type. - Reference to the calling object. - - - Returns true if this reference refers to an enumeration type. - This reference refers to an enumeration type. - Reference to the calling object. - - - Returns true if this reference refers to a floating point type. - This reference refers to a floating point type. - Reference to the calling object. - - - Returns true if this reference refers to a GUID type. - This reference refers to a GUID type. - Reference to the calling object. - - - Returns true if this reference refers to an Int16 type. - This reference refers to an Int16 type. - Reference to the calling object. - - - Returns true if this reference refers to an Int32 type. - This reference refers to an Int32 type. - Reference to the calling object. - - - Returns true if this reference refers to an Int64 type. - This reference refers to an Int64 type. - Reference to the calling object. - - - Returns true if this primitive type kind represents an integer type. - This kind refers to an integer type. - Reference to the calling object. - - - Returns true if this reference refers to an integer type. - This reference refers to an integer type. - Reference to the calling object. - - - Determines if a type is equivalent to or derived from another type. - True if and only if the thisType is equivalent to or inherits from otherType. - Type to be tested for equivalence to or derivation from the other type. - Type that is the other type. - - - Returns true if this reference refers to a primitive type. - This reference refers to a primitive type. - Reference to the calling object. - - - Returns true if this reference refers to a row type. - This reference refers to a row type. - Reference to the calling object. - - - Returns true if this reference refers to an SByte type. - This reference refers to an SByte type. - Reference to the calling object. - - - Returns true if this reference refers to a signed integral type. - This reference refers to a signed integral type. - Reference to the calling object. - - - Returns true if this reference refers to a single type. - This reference refers to a single type. - Reference to the calling object. - - - Returns true if this type kind represents a spatial type. - This kind refers to a spatial type. - Reference to the calling object. - - - Returns true if this definition refers to a spatial type. - This definition refers to a spatial type. - Definition to the calling object. - - - Returns true if this reference refers to a spatial type. - This reference refers to a spatial type. - Reference to the calling object. - - - Returns true if this reference refers to a stream type. - This reference refers to a stream type. - Reference to the calling object. - - - Returns true if this reference refers to a string type. - This reference refers to a string type. - Reference to the calling object. - - - Returns true if this type kind represents a structured type. - This kind refers to a structured type. - Reference to the calling object. - - - Returns true if this reference refers to a structured type. - This reference refers to a structured type. - Reference to the calling object. - - - Returns true if this type kind represents a temporal type. - This kind refers to a temporal type. - Reference to the calling object. - - - Returns true if this reference refers to a temporal type. - This reference refers to a temporal type. - Reference to the calling object. - - - Returns true if this reference refers to a time type. - This reference refers to a time type. - Reference to the calling object. - - - Returns the primitive kind of the definition of this reference. - The primitive kind of the definition of this reference. - Reference to the calling object. - - - Contains extension methods for interfaces. - - - - - - - - - - - - - - Gets the entity type declaring this navigation property. - The entity type that declares this navigation property. - Reference to the calling object. - - - Gets the direct value annotations for an element. - The immediate value annotations of the element. - The model containing the annotations. - The annotated element. - - - - Gets the entity containers belonging to this model. - Entity containers belonging to this model. - Model to search for entity containers. - - - - - - - - Searches for an entity container with the given name in this model and all referenced models and returns null if no such entity container exists. - The requested entity container, or null if no such entity container exists. - The model to search. - The qualified name of the entity container being found. - - - Searches for functions with the given name in this model and all referenced models and returns an empty enumerable if no such functions exist. - The requested functions. - The model to search. - The qualified name of the functions being found. - - - - Finds a property of a record expression. - The property, if found, otherwise null. - The record expression. - Name of the property to find. - - - - Gets the binding of a property of the type term of a type annotation. - The binding of the property in the type annotation, or null if no binding exists. - Annotation to search. - Property to search for. - - - Gets the binding of a property of the type term of a type annotation. - The binding of the property in the type annotation, or null if no binding exists. - Annotation to search. - Name of the property to search for. - - - Searches for a type with the given name in this model and all referenced models and returns null if no such type exists. - The requested type, or null if no such type exists. - The model to search. - The qualified name of the type being found. - - - Searches for a value term with the given name in this model and all referenced models and returns null if no such value term exists. - The requested value term, or null if no such value term exists. - The model to search. - The qualified name of the value term being found. - - - Gets an annotatable element's vocabulary annotations defined in a specific model and models referenced by that model. - Annotations attached to the element by this model or by models referenced by this model. - The model to search. - Element to check for annotations. - - - Gets an annotatable element's vocabulary annotations that bind a particular term. - Annotations attached to the element by this model or by models referenced by this model that bind the term. - Model to search. - Element to check for annotations. - Term to search for. - Type of the annotation being returned. - - - Gets an annotatable element's vocabulary annotations that bind a particular term. - Annotations attached to the element by this model or by models referenced by this model that bind the term with the given qualifier. - Model to search. - Element to check for annotations. - Term to search for. - Qualifier to apply. - Type of the annotation being returned. - - - Gets an annotatable element's vocabulary annotations that bind a particular term. - Annotations attached to the element by this model or by models referenced by this model that bind the term. - Model to search. - Element to check for annotations. - Name of the term to search for. - Type of the annotation being returned. - - - Gets an annotatable element's vocabulary annotations that bind a particular term. - Annotations attached to the element by this model or by models referenced by this model that bind the term with the given qualifier. - Model to search. - Element to check for annotations. - Name of the term to search for. - Qualifier to apply. - Type of the annotation being returned. - - - Gets an annotatable element's vocabulary annotations defined in a specific model and models referenced by that model. - Annotations attached to the element (or, if the element is a type, to its base types) by this model or by models referenced by this model. - The model to search. - Element to check for annotations. - - - - - - Gets an annotation value from an annotatable element. - The model containing the annotation. - The annotated element. - Type of the annotation being returned. - - - Gets an annotation value corresponding to the given namespace and name provided. - The model containing the annotation. - The annotated element. - Namespace of the annotation. - Name of the annotation inside the namespace. - Type of the annotation being returned. - - - Gets an annotation value corresponding to the given namespace and name provided. - The requested annotation value, if it exists. Otherwise, null. - The model containing the annotation. - The annotated element. - Namespace of the annotation. - Name of the annotation inside the namespace. - - - Retrieves a set of annotation values. For each requested value, returns null if no annotation with the given name exists for the given element. - The model in which to find the annotations. - The set of requested annotations. - - - Gets documentation for a specified element. - Documentation that exists on the element. Otherwise, null. - The model containing the documentation. - The element. - - - - Gets the of a property of a term type that has been applied to the type of a value. - Value of the property evaluated against the supplied value, or null if no relevant type annotation exists. - Model to search for type annotations. - Value to use as context in evaluation. - Property to evaluate. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a property of a term type that has been applied to the type of a value. - Model to search for type annotations. - Value to use as context in evaluation. - Property to evaluate. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - Gets the of a property of a term type that has been applied to the type of a value. - Value of the property evaluated against the supplied value, or null if no relevant type annotation exists. - Model to search for type annotations. - Value to use as context in evaluation. - Property to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a property of a term type that has been applied to the type of a value. - Model to search for type annotations. - Value to use as context in evaluation. - Property to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - Gets the of a vocabulary term that has been applied to the type of a value. - Value of the term evaluated against the supplied value. - Model to search for term annotations. - Value to use as context in evaluation. - Term to evaluate. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a vocabulary term that has been applied to the type of a value. - Model to search for term annotations. - Value to use as context in evaluation. - Term to evaluate. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - Gets the of a vocabulary term that has been applied to the type of a value. - Value of the term evaluated against the supplied value. - Model to search for term annotations. - Value to use as context in evaluation. - Term to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a vocabulary term that has been applied to the type of a value. - Model to search for term annotations. - Value to use as context in evaluation. - Term to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - Gets the of a vocabulary term that has been applied to the type of a value. - Value of the term evaluated against the supplied value. - Model to search for term annotations. - Value to use as context in evaluation. - Name of the term to evaluate. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a vocabulary term that has been applied to the type of a value. - Model to search for term annotations. - Value to use as context in evaluation. - Name of the term to evaluate. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - Gets the of a vocabulary term that has been applied to the type of a value. - Value of the term evaluated against the supplied value. - Model to search for term annotations. - Value to use as context in evaluation. - Name of the term to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - - - Gets the CLR value of a vocabulary term that has been applied to the type of a value. - Model to search for term annotations. - Value to use as context in evaluation. - Name of the term to evaluate. - Qualifier to apply. - Evaluator to use to perform expression evaluation. - The CLR type of the value to be returned. - - - - - - - - Gets the multiplicity of this end of a bidirectional relationship between this navigation property and its partner. - The multiplicity of this end of the relationship. - Reference to the calling object. - - - - - - - - - Gets all schema elements from the model, and models referenced by it. - Schema elements from the model, and models referenced by it. - Model to search for elements - - - Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed. - The model containing the annotation. - The annotated element. - Namespace that the annotation belongs to. - Name of the annotation within the namespace. - Value of the new annotation. - - - Sets an annotation value on an annotatable element. - The model containing the annotation. - The annotated element. - Value of the new annotation. - Type of the annotation being set. - - - Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed. - The model in which to set the annotations. - The annotations to set. - - - Sets documentation for a specified element. - The model containing the documentation. - The element. - Documentation to set. - - - - - - - Gets the entity type targeted by this navigation property. - The entity type targeted by this navigation property. - Reference to the calling object. - - - Analyzes .EntitySet expression and returns a relative path to an if available. The path starts with the parameter and may have optional sequence of and type casts segments. - True if the entity set expression of the functionImport contains a relative path an , otherwise false. - The function import containing the entity set expression. - The model containing the function import. - The function import parameter from which the relative entity set path starts. - The optional sequence of navigation properties. - - - Analyzes .EntitySet expression and returns a static reference if available. - True if the entity set expression of the functionImport contains a static reference to an , otherwise false. - The function import containing the entity set expression. - The static entity set of the function import. - - - - - - Gets an annotatable element's vocabulary annotations as seen from a particular model. - Annotations attached to the element by the model or by models referenced by the model. - Reference to the calling object. - Model to check for annotations. - - - Represents a reference to an EDM binary type. - - - Gets a value indicating whether this type specifies fixed length. - True if the type specifies fixed length; otherwise, false. - - - Gets a value indicating whether this type specifies the maximum allowed max length. - True if the type specifies the maximum allowed max length; otherwise, false. - - - Gets the maximum length of this type. - The maximum length of this type. - - - Defines an EDM component who is invalid or whose validity is unknown at construction. - - - Gets an error if one exists with the current object. - An error. - - - Represents a definition of an EDM collection type. - - - Gets the element type of this collection. - The element type of this collection. - - - Represents a reference to an EDM collection type. - - - Represents a definition of an EDM complex type. - - - Represents a reference to an EDM complex type. - - - Represents a reference to an EDM decimal type. - - - Gets the precision of this type. - The precision of this type. - - - Gets the scale of this type. - The scale of this type. - - - Represents an EDM documentation. - - - Gets a long description of this documentation. - A long description of this documentation. - - - Gets a summary of this documentation. - A summary of this documentation. - - - Represents an EDM element. - - - Represents an EDM entity container. - - - Gets a collection of the elements of this entity container. - A collection of the elements of this entity container. - - - Searches for an entity set with the given name in this entity container and returns null if no such set exists. - The requested element, or null if the element does not exist. - The name of the element being found. - - - Searches for function imports with the given name in this entity container and returns null if no such function import exists. - A group of the requested function imports, or null if no such function import exists. - The name of the function import being found. - - - Represents the common elements of all EDM entity container elements. - - - Gets the container that contains this element. - - - - Represents a definition of an EDM entity reference type. - - - Gets the entity type pointed to by this entity reference. - The entity type pointed to by this entity reference. - - - Represents a reference to an EDM entity reference type. - - - Represents an EDM entity set. - - - Gets the entity type contained in this entity set. - The entity type contained in this entity set. - - - Finds the entity set that a navigation property targets. - The entity set that the navigation propertion targets, or null if no such entity set exists. - The navigation property. - - - Gets the navigation targets of this entity set. - - - Represents a definition of an EDM entity type. - - - Gets the structural properties of the entity type that make up the entity key. - The structural properties of the entity type. - - - Represents a reference for the definition of an EDM entity type. - - - Represents a definition of an EDM enumeration type member. - - - Gets the type that this member belongs to. - The type that this member belongs to. - - - Gets the value of this enumeration type member. - The value of this enumeration type member. - - - Represents a definition of an EDM enumeration type. - - - Gets the members of this enumeration type. - The members of this enumeration type. - - - Gets a value indicating whether the enumeration type can be treated as a bit field. - True if the value indicating whether the enumeration type can be treated as a bit field; otherwise, false. - - - Gets the underlying type of this enumeration type. - The underlying type of this enumeration type. - - - Represents a reference for a definition of an EDM enumeration type. - - - Represents an EDM function. - - - Gets the defining expression of this function. - The defining expression of this function. - - - Represents the common base type of EDM functions and function imports. - - - Searches for a parameter with the given name, and returns null if no such parameter exists. - The requested parameter or null if no such parameter exists. - The name of the parameter being found. - - - Gets the collection of parameters for this function. - The collection of parameters for this function. - - - Gets the return type of this function. - The return type of this function. - - - Represents an EDM function import. - - - Gets a value indicating whether this function import can be used as an extension method for the type of the first parameter of this function import. - True if the function import can be used as an extension method for the type of the first parameter of this function import; otherwise, false. - - - Gets a value indicating whether this function import can be composed inside expressions. cannot be set to true if is set to true. - True if the function import can be composed inside expressions; otherwise, false. - - - Gets the entity set where the result of this function import will be contained in. - The entity set where the result of this function import will be contained in. - - - Gets a value indicating whether this function import has side-effects. cannot be set to true if is set to true. - True if the function import has side-effects; otherwise, false. - - - Represents a parameter of an EDM function. - - - Gets the function or function import that declared this parameter. - - - Gets the mode of this function parameter. - The mode of this function parameter. - - - Gets the type of this function parameter. - The type of this function parameter. - - - Represents the interface for all EDM elements that can be located. - - - Gets the location of this element. - The location of this element. - - - Semantic representation of an EDM model. - - - Gets the model's annotations manager. - - - Searches for an entity container with the given name in this model and returns null if no such entity container exists. - The requested entity container, or null if no such entity container exists. - The name of the entity container being found. - - - Searches for functions with the given name in this model and returns an empty enumerable if no such function exists. - A set of functions sharing the specified qualified name, or an empty enumerable if no such function exists. - The qualified name of the function being found. - - - Searches for a type with the given name in this model and returns null if no such type exists. - The requested type, or null if no such type exists. - The qualified name of the type being found. - - - Searches for a value term with the given name in this model and returns null if no such value term exists. - The requested value term, or null if no such value term exists. - The qualified name of the value term being found. - - - Searches for vocabulary annotations specified by this model. - The vocabulary annotations for the element. - The annotated element. - - - Gets the collection of models referred to by this model. - The collection of models referred to by this model. - - - Gets the collection of schema elements that are contained in this model. - The collection of schema elements that are contained in this model. - - - Gets the collection of vocabulary annotations that are contained in this model. - The collection of vocabulary annotations. - - - Common base interface for all named EDM elements. - - - Gets the name of this element. - The name of this element. - - - Represents an EDM navigation property. - - - Gets a value indicating whether the navigation target is contained inside the navigation source. - - - Gets the dependent properties of this navigation property, returning null if this is the principal end or if there is no referential constraint. - - - Gets whether this navigation property originates at the principal end of an association. - - - Gets the action to execute on the deletion of this end of a bidirectional association. - - - Gets the partner of this navigation property. - - - Represents a definition of an EDM primitive type. - - - Gets the primitive kind of this type. - The primitive kind of this type. - - - Represents a reference to definition of an EDM primitive type. - - - Represents an EDM property. - - - Gets the type that this property belongs to. - The type that this property belongs to. - - - Gets the kind of this property. - The kind of this property. - - - Gets the type of this property. - The type of this property. - - - Represents an EDM row type. - - - Represents a reference to an EDM row type. - - - Common base interface for all named children of EDM schemata. - - - Gets the namespace this schema element belongs to. - The namespace this schema element belongs to. - - - Gets the kind of this schema element. - The kind of this schema element. - - - Represents an EDM schema type. - - - Represents a reference to an EDM spatial type. - - - Gets the spatial reference identifier of this spatial type. - The spatial reference identifier of this spatial type. - - - Represents a reference to an EDM string type. - - - Gets a string representing the collation of this string type. - A string representing the collation of this string type. - - - Gets a value indicating whether this string type specifies fixed length. - True if this string type specifies fixed length; otherwise, false. - - - Gets a value indicating whether this string type specifies the maximum allowed maximum length. - True if this string type specifies the maximum allowed maximum length; otherwise, false. - - - Gets a value indicating whether this string type supports Unicode encoding. - True if this string type supports Unicode encoding; otherwise, false. - - - Gets the maximum length of this string type. - The maximum length of this string type. - - - Represents an EDM structural (that is, non-navigation) property. - - - Gets the concurrency mode of this property. - The concurrency mode of this property. - - - Gets the default value of this property. - The default value of this property. - - - Represents the common base interface for definitions of EDM structured types. - - - Gets the base type of this type. - The base type of this type. - - - Gets the properties declared immediately within this type. - The properties declared immediately within this type. - - - Searches for a structural or navigation property with the given name in this type and all base types and returns null if no such property exists. - The requested property, or null if no such property exists. - The name of the property being found. - - - Gets a value indicating whether this type is abstract. - True if this type is abstract; otherwise, false. - - - Gets a value indicating whether this type is open. - True if this type is open; otherwise, false. - - - Represents a reference to an EDM structured type. - - - Represents a reference to an EDM temporal (Time, DateTime, DateTimeOffset) type. - - - Gets the precision of this temporal type. - The precision of this temporal type. - - - Represents the term to which an annotation can bind. - - - Gets the kind of a term. - The kind of a term. - - - Represents the definition of an EDM type. - - - Gets the kind of this type. - The kind of this type. - - - Represents a reference to an EDM type. - - - Gets the definition to which this type refers. - The definition to which this type refers. - - - Gets a value indicating whether this type is nullable. - true of the type is nullable; otherwise, false. - - - Represents an EDM value term. - - - Gets the type of the term. - The type of the term. - - - - Contains ToTraceString() extension methods. - - - Returns the text representation of the current object. - The text representation of the current object. - Reference to the calling object. - - - Returns the text representation of the current object. - The text representation of the current object. - Reference to the calling object. - - - Returns the text representation of the current object. - The text representation of the current object. - Reference to the calling object. - - - Returns the text representation of the current object. - The text representation of the current object. - Reference to the calling object. - - - Returns the text representation of the current object. - The text representation of the current object. - Reference to the calling object. - - - Represents an EDM annotation with an immediate value. - - - Gets the namespace Uri of the annotation. - - - Gets the value of this annotation. - - - Represents the combination of an EDM annotation with an immediate value and the element to which it is attached. - - - Gets the element to which the annotation is attached - - - Gets the local name of this element. - - - Gets the namespace of the annotation. - - - Gets the value of this annotation. - - - Manages getting and setting direct value annotations on EDM elements. - - - Retrieves an annotation value for an EDM element. Returns null if no annotation with the given name exists for the given element. - Returns the annotation value that corresponds to the provided name. Returns null if no annotation with the given name exists for the given element. - The annotated element. - Namespace that the annotation belongs to. - Local name of the annotation. - - - Retrieves a set of annotation values. For each requested value, returns null if no annotation with the given name exists for the given element. - The set of requested annotations - - - Gets annotations associated with an element. - The direct value annotations for the element. - The annotated element. - - - Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed. - The annotated element. - Namespace that the annotation belongs to. - Name of the annotation within the namespace. - The value of the annotation. - - - Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed. - The annotations to set - - - Represents a property binding specified as part of an EDM Type Annotation. - - - Gets the property given a value by the annotation. - The property given a value by the annotation. - - - Gets the expression producing the value of the annotation. - The expression producing the value of the annotation. - - - Represents an EDM Type Annotation. - - - Gets the value annotations for the properties of the type. - The value annotations for the properties of the type. - - - Represents an EDM Value Annotation. - - - Gets the expression producing the value of the annotation. - The expression producing the value of the annotation. - - - Represents an EDM Vocabulary Annotation. - - - Gets the qualifier used to discriminate between multiple bindings of the same property or type. - The qualifier. - - - Gets the element the annotation applies to. - The element the annotation applies to. - - - Gets the term bound by the annotation. - - - Represents the constants for CSDL XML. - - - Version 1.0 of EDMX. Corresponds to EDMX namespace "http://schemas.microsoft.com/ado/2007/06/edmx". - - - Version 2.0 of EDMX. Corresponds to EDMX namespace "http://schemas.microsoft.com/ado/2008/10/edmx". - - - Version 3.0 of EDMX. Corresponds to EDMX namespace "http://schemas.microsoft.com/ado/2009/11/edmx". - - - The current latest version of EDMX. - - - Defines a location in a XML file. - - - Gets the line number in the file. - The line number in the file. - - - Gets the position in the line. - The position in the line. - - - Gets a string representation of the location. - A string representation of the location. - - - Provides CSDL parsing services for EDM models. - - - Returns an IEdmModel for the given CSDL artifacts. - Success of the parse operation. - Collection of XmlReaders containing the CSDL artifacts. - Model to be references by the created model. - The model generated by parsing. - Errors reported while parsing. - - - Returns an IEdmModel for the given CSDL artifacts. - Success of the parse operation. - Collection of XmlReaders containing the CSDL artifacts. - The model generated by parsing. - Errors reported while parsing. - - - Returns an IEdmModel for the given CSDL artifacts. - Success of the parse operation. - Collection of XmlReaders containing the CSDL artifacts. - Models to be references by the created model. - The model generated by parsing. - Errors reported while parsing. - - - Provides CSDL serialization services for EDM models. - - - - Outputs a CSDL artifact to the provided writer. - A value indicating whether serialization was successful. - Model to be written. - XmlWriter the generated CSDL will be written to. - Errors that prevented successful serialization, or no errors if serialization was successful. - - - Represents whether a vocabulary annotation should be serialized within the element it applies to or in a separate section of the CSDL. - - - The annotation should be serialized within the element being annotated. - - - The annotation should be serialized in a separate section. - - - Provides EDMX parsing services for EDM models. - - - Returns an IEdmModel for the given EDMX artifact. - Success of the parse operation. - XmlReader containing the EDMX artifact. - Model to be referenced by the created model. - The model generated by parsing - Errors reported while parsing. - - - Returns an IEdmModel for the given EDMX artifact. - Success of the parse operation. - XmlReader containing the EDMX artifact. - The model generated by parsing - Errors reported while parsing. - - - Returns an IEdmModel for the given EDMX artifact. - Success of the parse operation. - XmlReader containing the EDMX artifact. - Models to be references by the created model. - The model generated by parsing - Errors reported while parsing. - - - Specifies what target of an EDMX file. - - - The target is Entity Framework. - - - The target is OData. - - - Provides EDMX serialization services for EDM models. - - - Outputs an EDMX artifact to the provided XmlWriter. - A value indicating whether serialization was successful. - Model to be written. - XmlWriter the generated EDMX will be written to. - Target implementation of the EDMX being generated. - Errors that prevented successful serialization, or no errors if serialization was successfull. - - - Contains extension methods for interfaces that are useful to serialization. - - - Gets the annotations associated with the association serialized for a navigation property. - Model containing the navigation property. - The navigation property. - The association annotations. - The annotations for association end 1. - The annotations for association end 2. - The annotations for the referential constraint. - - - Gets the name used for the association end serialized for a navigation property. - The association end name. - Model containing the navigation property. - The navigation property. - - - Gets the fully-qualified name used for the association serialized for a navigation property. - The fully-qualified association name. - Model containing the navigation property. - The navigation property. - - - Gets the name used for the association serialized for a navigation property. - The association name. - Model containing the navigation property. - The navigation property. - - - Gets the namespace used for the association serialized for a navigation property. - The association namespace. - Model containing the navigation property. - The navigation property. - - - Gets the annotations associated with the association serialized for a navigation target of an entity set. - Model containing the entity set. - The entity set. - The navigation property. - The association set annotations. - The annotations for association set end 1. - The annotations for association set end 2. - - - Gets the name used for the association set serialized for a navigation property of an entity set. - The association set name. - Model containing the entity set. - The entity set. - The navigation property. - - - - - Gets an annotation indicating if the value should be serialized as an element. - Value indicating if the string should be serialized as an element. - Value the annotation is on. - Model containing the value. - - - Gets an annotation indicating whether the value of an enum member should be explicitly serialized. - Whether the member should have its value serialized. - The member the annotation is on. - Model containing the member. - - - - - Gets the primary end of a pair of partnered navigation properties, selecting the principal end if there is one and making a stable, arbitrary choice otherwise. - The primary end between the navigation property and its partner. - The navigation property. - - - Gets the schema an annotation should be serialized in. - Name of the schema the annotation belongs to. - Reference to the calling annotation. - Model containing the annotation. - - - Gets the location an annotation should be serialized in. - The location the annotation should be serialized at. - Reference to the calling annotation. - Model containing the annotation. - - - Sets the annotations for the association serialized for a navigation property. - Model containing the navigation property. - The navigation property. - The association annotations. - The annotations for association end 1. - The annotations for association end 2. - The annotations for the referential constraint. - - - Sets the name used for the association end serialized for a navigation property. - Model containing the navigation property. - The navigation property. - The association end name. - - - Sets the name used for the association serialized for a navigation property. - Model containing the navigation property. - The navigation property. - The association name. - - - Sets the namespace used for the association serialized for a navigation property. - Model containing the navigation property. - The navigation property. - The association namespace. - - - Sets the annotations for the association set serialized for a navigation target of an entity set. - Model containing the entity set. - The entity set. - The navigation property. - The association set annotations. - The annotations for association set end 1. - The annotations for association set end 2. - - - Sets the name used for the association set serialized for a navigation property of an entity set. - Model containing the entity set. - The entity set - The navigation property. - The association set name. - - - - - Sets an annotation indicating if the value should be serialized as an element. - Value to set the annotation on. - Model containing the value. - Value indicating if the value should be serialized as an element. - - - Sets an annotation indicating whether the value of an enum member should be explicitly serialized. - Member to set the annotation on. - Model containing the member. - If the value of the enum member should be explicitly serialized - - - - - Sets the schema an annotation should appear in. - The annotation the schema should be set for. - Model containing the annotation. - The schema the annotation belongs in. - - - Sets the location an annotation should be serialized in. - The annotation the location is being specified for. - Model containing the annotation. - The location the annotation should appear. - - - - to CLR value converter. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - The delegate customizing conversion of structured values. - - - Converts edmValue to a value. - Converted boolean. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted byte. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a CLR byte array value. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted char. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a value. - Converted DateTime. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted DateTimeOffset. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted decimal. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted double. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted integer. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a value. - Converted integer. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a value. - Converted integer. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted single. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted string. - The EDM value to be converted. - edmValue - - - Converts edmValue to a value. - Converted Time. - The EDM value to be converted. - edmValue - - - Converts edmValue to a CLR value of the specified type. Supported values for <typeparamref name="T" /> are: CLR primitive types such as and , CLR enum types, <see cref="T:System.Collections.Generic.IEnumerable`1" />, <see cref="T:System.Collections.Generic.ICollection`1" />, <see cref="T:System.Collections.Generic.IList`1" />, CLR classes with default constructors and public properties with setters and collection properties of the following shapes: <see cref="T:System.Collections.Generic.IEnumerable`1" /> EnumerableProperty { get; set; }, <see cref="T:System.Collections.Generic.ICollection`1" /> CollectionProperty { get; set; }, <see cref="T:System.Collections.Generic.IList`1" /> ListProperty { get; set; }, <see cref="T:System.Collections.Generic.ICollection`1" /> CollectionProperty { get { return this.nonNullCollection; } }, <see cref="T:System.Collections.Generic.IList`1" /> ListProperty { get { return this.nonNullList; } }. - The EDM value to be converted. - The CLR type. - - - Converts edmValue to a CLR value of the specified type. Supported values for clrType are: CLR primitive types such as and , CLR enum types, <see cref="T:System.Collections.Generic.IEnumerable`1" />, <see cref="T:System.Collections.Generic.ICollection`1" />, <see cref="T:System.Collections.Generic.IList`1" />, CLR classes with default constructors and public properties with setters and collection properties of the following shapes: <see cref="T:System.Collections.Generic.IEnumerable`1" /> EnumerableProperty { get; set; }, <see cref="T:System.Collections.Generic.ICollection`1" /> CollectionProperty { get; set; }, <see cref="T:System.Collections.Generic.IList`1" /> ListProperty { get; set; }, <see cref="T:System.Collections.Generic.ICollection`1" /> CollectionProperty { get { return this.nonNullCollection; } }, <see cref="T:System.Collections.Generic.IList`1" /> ListProperty { get { return this.nonNullList; } }. - A CLR value converted from edmValue. - The EDM value to be converted. - The CLR type. - - - Converts edmValue to a nullable value. - Converted boolean. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted byte. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a value. - Converted char. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a nullable value. - Converted DateTime. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted DateTimeOffset. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted decimal. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted double. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted integer. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a value. - Converted integer. - The EDM value to be converted. - edmValue - edmValue - - - Converts edmValue to a nullable value. - Converted integer. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted single. - The EDM value to be converted. - edmValue - - - Converts edmValue to a nullable value. - Converted Tim. - The EDM value to be converted. - edmValue - - - Registers the clrObject corresponding to the edmValue. All subsequent conversions from this edmValue performed by this instance of will return the specified clrObject. Registration is required to support graph consistency and loops during conversion process. This method should be called inside the delegate if the delegate is calling back into in order to populate properties of the clrObject. - The EDM value. - The CLR object. - - - - Expression evaluator. - - - - - Evaluates an expression with no value context. - The value that results from evaluating the expression in the context of the supplied value. - Expression to evaluate. The expression must not contain paths, because no context for evaluating a path is supplied. - - - Evaluates an expression in the context of a value. - The value that results from evaluating the expression in the context of the supplied value. - Expression to evaluate. - Value to use as context in evaluating the expression. - - - Evaluates an expression in the context of a value and a target type. - The value that results from evaluating the expression in the context of the supplied value, asserted to be of the target type. - Expression to evaluate. - Value to use as context in evaluating the expression. Cannot be null if the expression contains paths. - Type to which the result value is expected to conform. - - - Expression evaluator capable of producing CLR values. - - - - - Gets or sets an instance of that is used to produce CLR values during evaluation. - - - Evaluates an expression with no value context. - Expression to evaluate. The expression must not contain paths, because no context for evaluating a path is supplied. - The CLR type of the value to be returned. - - - Evaluates an expression in the context of a value. - Expression to evaluate. - Value to use as context in evaluating the expression. - The CLR type of the value to be returned. - - - Evaluates an expression in the context of a value and a target type. - Expression to evaluate. - Value to use as context in evaluating the expression. - Type to which the result value is expected to conform. - The CLR type of the value to be returned. - - - Defines EDM expression kinds. - - - - - - Represents an expression implementing . - - - - - - - - - Represents an expression implementing . - - - - - - - - - Represents an expression implementing . - - - - - - - - - Represents an expression implementing . - - - Represents an expression implementing . - - - - - - - - - - - - - - - - - - - - - - - - - - - Represents an expression implementing . - - - - - - - - - - - - - - - Represents an expression implementing . - - - Represents an expression implementing - - - Represents an EDM type assertion expression. - - - Gets the expression for which the type is asserted. - The expression for which the type is asserted. - - - Gets the asserted type. - The asserted type. - - - - Represents an EDM boolean constant expression. - - - Represents an EDM multi-value construction expression. - - - Gets the declared type of the collection, or null if there is no declared type. - - - Gets the constructed element values. - The constructed element values. - - - Represents an EDM DateTime constant expression. - - - - Represents an EDM decimal constant expression. - - - Represents an EDM entity set reference expression. - - - Gets the referenced entity set. - The referenced entity set. - - - Represents an EDM enumeration member reference expression. - - - Gets the referenced enum member. - - - Represents an EDM expression. - - - Gets the kind of this expression. - The kind of this expression. - - - Represents an EDM floating constant expression. - - - Represents an EDM function application expression. - - - Gets the applied function. - The applied function. - - - Gets the arguments to the function. - The arguments to the function. - - - Represents an EDM function reference expression. - - - Gets the referenced function. - - - - Represents an EDM if expression. - - - Gets the expression to evaluate if Test evaluates to False. - The expression to evaluate if Test evaluates to False. - - - Gets the expression to evaluate if Test evaluates to True. - The expression to evaluate if Test evaluates to True. - - - Gets the test expression. - The test expression. - - - Represents an EDM integer constant expression. - - - Represents an EDM type test expression. - - - Gets the expression whose type is to be tested. - The expression whose type is to be tested. - - - Gets the type to be tested against. - The type to be tested against. - - - Represents an EDM labeled expression element. - - - Gets the underlying expression. - - - Represents a reference to an EDM labeled expression. - - - Gets the referenced expression. - - - - Represents an EDM parameter reference expression. - - - Gets the referenced parameter. - - - Represents an EDM path expression. - - - Gets the path as a decomposed qualified name. "A.B.C" is { "A", "B", "C" }. - The path as a decomposed qualified name. - - - Represents an EDM property constructor specified as part of a CSDL Record expression. - - - Gets the name of the property - The name of the property. - - - Gets the expression for the value of the property. - The expression for the value of the property. - - - Represents an EDM property reference expression. - - - - Gets the referenced property. - - - Represents an EDM record construction expression. - - - Gets the declared type of the record, or null if there is no declared type. - The declared type of the record, or null if there is no declared type. - - - Gets the constructed property values. - The constructed property values. - - - Represents an EDM string constant expression. - - - - Represents an EDM value term reference expression. - - - Gets the expression for the structured value containing the referenced term property. - The expression for the structured value containing the referenced term property. - - - Gets the optional qualifier. - The optional qualifier. - - - Gets the referenced value term. - The referenced value term. - - - Represents a reference to an EDM binary type. - - - Initializes a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Initializes a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - Denotes whether the maximum length is the maximum allowed value. - The maximum length of a value of this type. - Denotes whether the length can vary. - - - Gets a value indicating whether this type specifies fixed length. - true if this type specifies fixed length; otherwise, false. - - - Gets a value indicating whether this type specifies the maximum allowed max length. - true if this type specifies the maximum allowed maximum length; otherwise, false. - - - Gets the maximum length of this type. - The maximum length of this type. - - - Represents a definition of an EDM collection type. - - - Initializes a new instance of the EdmCollectionType class. - The type of the elements in this collection. - - - - Gets the kind of this type. - - - Represents a reference to an EDM collection type. - - - Initializes a new instance of the class. - The type definition this reference refers to. - Denotes whether the type can be nullable. - - - Gets the collection type to which this type refers. - The collection type to which this type refers. - - - Represents a definition of an EDM complex type. - - - Initializes a new instance of the EdmComplexType class. - The namespace this type belongs to. - The name of this type within its namespace. - - - Initializes a new instance of the EdmComplexType class. Note: Complex type inheritance is not supported in EDM version 3.0 and above. - The namespace this type belongs to. - The name of this type within its namespace. - The base type of this complex type. - Denotes whether this complex type is abstract. - Denotes whether this type is open. - - - Initializes a new instance of the EdmComplexType class. - The namespace this type belongs to. - The name of this type within its namespace. - Denotes whether this type is open. - - - - - - Gets the kind of this type. - - - Represents a reference to an EDM complex type. - - - Initializes a new instance of the class. - The type definition this reference refers to. - Denotes whether the type can be nullable. - - - Contains constant values that apply to the EDM model, regardless of source (for CSDL/EDMX specific constants see ). - - - Version 1.0 of EDM. Corresponds to CSDL namespace "http://schemas.microsoft.com/ado/2006/04/edm". - - - Version 1.1 of EDM. Corresponds to CSDL namespace "http://schemas.microsoft.com/ado/2007/05/edm". - - - Version 1.2 of EDM. Corresponds to CSDL namespace "http://schemas.microsoft.com/ado/2008/01/edm". - - - Version 2.0 of EDM. Corresponds to CSDL namespaces "http://schemas.microsoft.com/ado/2008/09/edm" and "http://schemas.microsoft.com/ado/2009/08/edm". - - - Version 3.0 of EDM. Corresponds to CSDL namespace "http://schemas.microsoft.com/ado/2009/11/edm". - - - The current latest version of EDM. - - - Provides predefined declarations relevant to EDM semantics. - - - Gets the model's annotations manager. - - - Searches for an entity container with the given name in this model and returns null if no such entity container exists. - The requested entity container, or null if no such entity container exists. - The name of the entity container being found. - - - Searches for functions with the given name in this model and returns an empty enumerable if no such function exists. - A set functions sharing the specified qualified name, or an empty enumerable if no such function exists. - The qualified name of the function being found. - - - Searches for a type with the given name in this model and returns null if no such type exists. - The requested type, or null if no such type exists. - The qualified name of the type being found. - - - Searches for a value term with the given name in this model and returns null if no such value term exists. - The requested value term, or null if no such value term exists. - The qualified name of the value term being found. - - - Searches for vocabulary annotations specified by this model or a referenced model for a given element. - The vocabulary annotations for the element. - The annotated element. - - - - - - - - Gets a reference to a datetime primitive type definition. - A new datetime type reference. - Flag specifying if the referenced type should be nullable. - - - Gets a reference to a datetime with offset primitive type definition. - A new datetime with offset type reference. - Flag specifying if the referenced type should be nullable. - - - - - - - - - - - - - - - - - - - - - - Gets a reference to a time primitive type definition. - A new time type reference. - Flag specifying if the referenced type should be nullable. - - - - - - - - Represents a reference to an EDM decimal type. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - The precision of values with this type. - The scale of values with this type. - - - Gets the precision of this type. - The precision of this type. - - - Gets the scale of this type. - The scale of this type. - - - Represents an EDM documentation. - - - Creates a new instance of the class. - - - Creates a new instance of the class. - A summary of the documentation. - A long description of the documentation. - - - Gets or sets a long description of this documentation. - A long description of this documentation. - - - Gets or sets a summary of this documentation. - A summary of this documentation. - - - Represents the common base class for all EDM elements. - - - Creates a new instance of the class. - - - Represents an EDM entity container. - - - Initializes a new instance of the EdmEntityContainer class. - Namespace of the entity container. - Name of the entity container. - - - Adds an entity container element to this entity container. - The element to add. - - - Creates and adds an entity set to this entity container. - Created entity set. - Name of the entity set. - The entity type of the elements in this entity set. - - - Creates and adds a function import to this entity container. - Created function import. - Name of the function import. - Return type of the function import. - - - Creates and adds a function import to this entity container. - Created function import. - Name of the function import. - Return type of the function import. - An entity set containing entities returned by this function import. The two expression kinds supported are and . - - - Creates and adds a function import to this entity container. - Created function import. - Name of the function import. - Return type of the function import. - An entity set containing entities returned by this function import. The two expression kinds supported are and . - A value indicating whether this function import has side-effects. - A value indicating whether this functon import can be composed inside expressions. - A value indicating whether this function import can be used as an extension method for the type of the first parameter of this function import. - - - Gets a collection of the elements of this entity container. - A collection of the elements of this entity container. - - - Searches for an entity set with the given name in this entity container and returns null if no such set exists. - The requested element, or null if the element does not exist. - The name of the element being found. - - - Searches for function imports with the given name in this entity container and returns null if no such function import exists. - A group of the requested function imports, or null if no such function import exists. - The name of the function import being found. - - - Gets or sets the name of this entity container. - The name of this entity container. - - - Gets the namespace of this entity container. - - - Gets the kind of this schema element. - - - Represents a definition of an EDM entity reference type. - - - - - Gets the kind of this type. - - - Represents a reference to an EDM entity reference type. - - - Creates a new instance of the class. - The definition referred to by this reference. - Denotes whether the type can be nullable. - - - Gets the entity reference definition to which this type refers. - The entity reference definition to which this type refers. - - - Represents an EDM entity set. - - - Initializes a new instance of the EdmEntitySet class. - An containing this entity set. - Name of the entity set. - The entity type of the elements in this entity set. - - - Adds a navigation target, specifying the destination entity set of a navigation property of an entity in this entity set. - The navigation property the target is being set for. - The destination entity set of the specified navigation property. - - - Gets or sets the container of this entity set. - - - - - Finds the entity set that a navigation property targets. - The entity set that the navigation propertion targets, or null if no such entity set exists. - The navigation property. - - - - Gets the navigation targets of this entity set. - - - Represents a definition of an EDM entity type. - - - Initializes a new instance of the EdmEntityType class. - Namespace the entity belongs to. - Name of the entity. - - - Initializes a new instance of the EdmEntityType class. - Namespace the entity belongs to. - Name of the entity. - The base type of this entity type. - - - Initializes a new instance of the EdmEntityType class. - Namespace the entity belongs to. - Name of the entity. - The base type of this entity type. - Denotes an entity that cannot be instantiated. - Denotes if the type is open. - - - Adds the keyProperties to the key of this entity type. - The key properties. - - - Adds the keyProperties to the key of this entity type. - The key properties. - - - Creates and adds a one-side navigation property to this type. Navigation property partner is created, but not added to navigationTargetType. - Created navigation property. - Name of the navigation property. - Type that this navigation property points to. - Multiplicity of the navigation target. - - - Creates and adds a one-side navigation property to this type. Navigation property partner is created, but not added to navigationTargetType. - Created navigation property. - Name of the navigation property. - Type that this navigation property points to. - Multiplicity of the navigation target. - Multiplicity of the navigation source. - - - Creates and adds a navigation property to this type and adds its navigation partner to navigationTargetType. - Created navigation property. - Name of the navigation property. - Type that this navigation property points to. - Multiplicity of the navigation target. - A value indicating whether the the navigation target is contained inside the navigation source. - An action to take when an instance of the navigation source type is deleted. - Name of the partner property. - Multiplicity of the navigation source. - A value indicating whether the the navigation source is contained inside the navigation target. - An action to take when an instance of the navigation target type is deleted. - - - Creates and adds a navigation property to this type and adds its navigation partner to navigationTargetType. - Created navigation property. - Name of the navigation property. - Type that this navigation property points to. - Multiplicity of the navigation target. - Name of the partner property. - Multiplicity of the navigation source. - - - - - - - - Gets the kind of this type. - - - Represents a reference to an EDM entity type. - - - Creates a new instance of the class. - The definition refered to by this reference. - Denotes whether the type can be nullable. - - - Represents a member of an EDM enumeration type. - - - Initializes a new instance of the EdmEnumMember class. - The type that declares this member. - Name of this enumeration member. - Value of this enumeration member. - - - Gets the type that this member belongs to. - - - Gets the value of this enumeration type member. - - - Represents the definition of an Edm enumeration type. - - - Initializes a new instance of the EdmEnumType class. - The underlying type of this enumeration type. - - - Initializes a new instance of the EdmEnumType class. - The underlying type of this enumeration type. - Namespace this enumeration type belongs to. - Name of this enumeration type. - A value indicating whether the enumeration type can be treated as a bit field. - - - Gets the members of this enumeration type. - - - Gets or sets the name of this enumeration type. - - - Gets or sets the namespace this schema element belongs to. - - - Removes an existing member from this enum type - The member to add. - - - Gets the kind of this schema element. - - - Gets or sets a value indicating whether the enumeration type can be treated as a bit field. - - - Gets the kind of this type. - - - Gets the underlying type of this enumeration type. - - - Represents a reference to an EDM enumeration type. - - - Creates a new instance of the class. - The definition refered to by this reference. - Denotes whether the type can be nullable. - - - Represents an EDM function. - - - Creates a new instance of the class. - Namespace of the function. - Name of the function. - Return type of the function. - - - Initializes a new instance of the EdmFunction class. - Namespace of the function. - Name of the function. - Return type of the function. - Defining expression of the function (for example an eSQL expression). - - - Gets or sets the defining expression of this function. - The defining expression of this function. - - - Gets or sets the namespace of this function. - The namespace of this function. - - - Gets the element kind of this function, which is always Function. - The element kind of this function. - - - Represents an EDM function or function import. - - - Creates a new instance of the class. - The name of the function. - The return type of the function. - - - Adds a parameter to this function (as the last parameter). - The parameter being added. - - - Adds a parameter to this function (as the last parameter). - The name of the parameter being added. - The type of the parameter being added. - - - Creates and adds a parameter to this function (as the last parameter). - Created parameter. - The name of the parameter being added. - The type of the parameter being added. - Mode of the parameter. - - - Searches for a parameter with the given name in this function and returns null if no such parameter exists. - The requested parameter, or null if no such parameter exists. - The name of the parameter to be found. - - - Gets or sets the name of this function. - The name of this function. - - - Gets the parameters of this function. - The parameters of this function. - - - Gets or sets the return type of this function. - The return type of this function. - - - Represents an EDM function import. - - - Initializes a new instance of class (side-effecting, non-composable, non-bindable). - An containing this function import. - Name of the function import. - Return type of the function import. - - - Initializes a new instance of class (side-effecting, non-composable, non-bindable). - An containing this function import. - Name of the function import. - Return type of the function import. - An entity set containing entities returned by this function import. The two expression kinds supported are and . - - - Initializes a new instance of class. - An containing this function import. - Name of the function import. - Return type of the function import. - An entity set containing entities returned by this function import. The two expression kinds supported are and . - A value indicating whether this function import has side-effects. - A value indicating whether this functon import can be composed inside expressions. - A value indicating whether this function import can be used as an extension method for the type of the first parameter of this function import. - - - - - Gets or sets the container of this function. - - - - - - Represents an EDM function parameter. - - - Initializes a new instance of the EdmFunctionParameter class. - Declaring function of the parameter. - Name of the parameter. - Type of the parameter. - - - Initializes a new instance of the EdmFunctionParameter class. - Declaring function of the parameter. - Name of the parameter. - Type of the parameter. - Mode of the parameter. - - - Gets the function or function import that declared this parameter. - - - Gets the mode of this parameter. - The mode of this parameter. - - - Gets the type of this parameter. - The type of this parameter. - - - Represents an EDM model. - - - - - - Adds a model reference to this model. - The model to reference. - - - Adds a vocabulary annotation to this model. - The annotation to be added. - - - Searches for vocabulary annotations specified by this model. - The vocabulary annotations for the element. - The annotated element. - - - - Removes an model reference from this model. - The model reference to be removed - - - Removes a vocabulary annotation from this model. - The annotation to be removed. - - - - Gets the collection of vocabulary annotations that are contained in this model. - - - Represents an EDM model. - - - Initializes a new instance of the EdmModelBase class. - Models to which this model refers. - Annotations manager for the model to use. - - - Adds a model reference to this model. - The model to reference. - - - Gets the model's annotations manager. - - - Searches for an entity container with the given name in this model and returns null if no such entity container exists. - The requested entity container, or null if no such entity container exists. - The name of the entity container being found. - - - Searches for a function with the given name in this model and returns null if no such function exists. - A group of functions sharing the specified qualified name, or an empty enumerable if no such function exists. - The qualified name of the function being found. - - - Searches for a type with the given name in this model and returns null if no such type exists. - The requested type, or null if no such type exists. - The qualified name of the type being found. - - - Searches for a value term with the given name in this model and returns null if no such value term exists. - The requested value term, or null if no such value term exists. - The qualified name of the value term being found. - - - Searches for vocabulary annotations specified by this model or a referenced model for a given element. - The vocabulary annotations for the element. - The annotated element. - - - - - Removes an model reference from this model. - The model reference to be removed - - - - - - Represents a common base class for all named EDM elements. - - - Creates a new instance of the class. - - - Creates a new instance of the class. - The name of the element. - - - The name of the element. - - - Gets the name of this element. - The name of this element. - - - Represents an EDM navigation property. - - - Adds the properties to the list of dependent properties. - The dependent properties. - - - Adds the properties to the list of dependent properties. - The dependent properties. - - - Gets a value indicating whether the navigation target is contained inside the navigation source. - - - Creates two navigation properties representing an association between two entity types. - Navigation property pointing from sourceEntityType to targetEntityType. - Navigation property name. - Navigation target type. - Navigation target multiplicity. - A value indicating whether the navigation source logically contains the navigation target. - Action to take upon deletion of an instance of the navigation source. - Navigation partner property name. - Navigation source type. - Navigation source multiplicity - A value indicating whether the navigation target logically contains the navigation source. - Action to take upon deletion of an instance of the navigation target. - - - Creates two navigation properties representing an association between two entity types. - Navigation property pointing from sourceEntityType to targetEntityType. - Navigation property name. - Navigation target type. - Navigation target multiplicity. - Navigation partner property name. - Navigation source type. - Navigation source multiplicity - - - Creates two navigation properties representing an association between two entity types. - Navigation property. - Navigation property name. - Type of the navigation property. - A value indicating whether the navigation source logically contains the navigation target. - Action to take upon deletion of an instance of the navigation source. - Navigation partner property name. - Type of the navigation partner property. - A value indicating whether the navigation target logically contains the navigation source. - Action to take upon deletion of an instance of the navigation target. - - - Gets the entity type that this navigation property belongs to. - The entity type that this navigation property belongs to. - - - Gets or sets the dependent properties of the association this navigation property expresses. - The dependent properties of the association this navigation property expresses. - - - Gets a value indicating whether this navigation property is from the principal end of the association. - - - Gets the partner of this navigation property. - - - Gets or sets the action to take when an element of the defining type is deleted. - The action to take when an element of the defining type is deleted. - - - Gets or sets the navigation property from this properties destination back to the declaring type of this property. - The navigation property from this properties destination back to the declaring type of this property. - - - Gets the kind of this property. - The kind of this property. - - - Represents a reference to an EDM primitive type. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Represents an EDM property. - - - Creates a new instance of the class. - The type that declares this property. - Name of the property. - Type of the property. - - - Gets the type that this property belongs to. - The type that this property belongs to. - - - Gets or sets the name of this property. - The name of this property. - - - Gets the kind of this property. - The kind of this property. - - - Gets or sets the type of this property. - The type of this property. - - - Represents a definition of an EDM row type. - - - - Gets the kind of this type. - - - Represents a reference to an EDM row type. - - - Creates a new instance of the class. - Type that describes this value. - Denotes whether the type can be nullable. - - - Represents a reference to an EDM spatial type. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - Spatial Reference Identifier for the spatial type being created. - - - Gets the precision of this temporal type. - The precision of this temporal type. - - - Represents a reference to an EDM string type. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - Denotes whether the max length is the maximum allowed value. - Maximum length of a value of this type. - Denotes whether the length can vary. - Denotes if string is encoded using Unicode. - Indicates the collation string to be used by the underlying store. - - - Gets a string representing the collation of this string type. - The collation of this string type. - - - Gets a value indicating whether this string type specifies fixed length. - True if this string type specifies fixed length; otherwise, false. - - - Gets a value indicating whether this string type specifies the maximum allowed max length. - True if this string type specifies the maximum allowed max length; otherwise, false. - - - Gets a value indicating whether this string type supports unicode encoding. - True if this string type supports Unicode encoding; otherwise, false. - - - Gets the maximum length of this string type. - The maximum length of this string type. - - - Represents an EDM structural (i.e. non-navigation) property. - - - Initializes a new instance of the EdmStructuralProperty class. - The type that declares this property. - Name of the property. - Type of the property. - - - Creates a new instance of the class. - The type that declares this property. - The name of the property. - The type of the property. - The default value of this property. - The concurrency mode of this property. - - - Gets the concurrency mode of this property. - The concurrency mode of this property. - - - Gets the default value of this property. - The default value of this property. - - - Gets the kind of this property. - The kind of this property. - - - Common base class for definitions of EDM structured types. - - - Initializes a new instance of the EdmStructuredType class. - - - Initializes a new instance of the EdmStructuredType class. - Denotes a structured type that cannot be instantiated. - Denotes if the type is open. - Base type of the type - - - - Creates and adds a structural property to this type. - Created structural property. - Name of the property. - Type of the property. - - - Creates and adds a structural property to this type. - Created structural property. - Name of the property. - Type of the property. - The default value of this property. - The concurrency mode of this property. - - - - - - - - - - Represents a reference to an EDM temporal (Time, DateTime, DateTimeOffset) type. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - - - Creates a new instance of the class. - The type this reference refers to. - Denotes whether the type can be nullable. - Precision of values with this type. - - - Gets the precision of this temporal type. - The precision of this temporal type. - - - Represents the definition of an EDM type. - - - Initializes a new instance of the class. - - - - - Represents a reference to an EDM type. - - - Creates a new instance of the class. - The type that describes this value. - Denotes whether the type can be nullable. - - - Gets the definition to which this type refers. - The definition to which this type refers. - - - Gets a value indicating whether this type is nullable. - True if this type is nullable; otherwise, false. - - - Returns the text representation of the current object. - The text representation of the current object. - - - Represents an EDM value term. - - - Initializes a new instance of the EdmValueTerm class. - Namespace of the term. - Name of the term within the namespace. - - - Initializes a new instance of the EdmValueTerm class. - Namespace of the term. - Name of the term within the namespace. - Type of the term. - - - Gets the local name of this term. - The local name of this term. - - - Gets the namespace of this term. - The namespace of this term. - - - Gets the schema element kind of this term. - The schema element kind of this term. - - - Gets the kind of this term. - The kind of this term. - - - Gets the type of this term. - The type of this term. - - - Represents an EDM annotation with an immediate native value. - - - Initializes a new instance of the class. - Namespace of the annotation. - Name of the annotation within the namespace. - Value of the annotation - - - The name of the annotation - - - The namespace Uri of the annotation. - - - Gets the value of this annotation. - - - Represents the combination of an EDM annotation with an immediate value and the element to which it is attached. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - Element to which the annotation is attached. - Namespace of the annotation. - Name of the annotation within the namespace. - - - Initializes a new instance of the class. - Element to which the annotation is attached. - Namespace of the annotation. - Name of the annotation within the namespace. - Value of the annotation - - - Gets or sets the element to which the annotation is attached. - - - Gets or sets the local name of the annotation - - - Gets or sets the namespace Uri of the annotation. - - - Gets the value of this annotation. - - - EdmDirectValueAnnotationsManager provides services for setting and getting transient annotations on elements. - - - Initializes a new instance of the EdmDirectValueAnnotationsManager class. - - - Retrieves an annotation value for an EDM element. Returns null if no annotation with the given name exists for the given element. - Returns the annotation that corresponds to the provided name. Returns null if no annotation with the given name exists for the given element. - The annotated element. - Namespace that the annotation belongs to. - Local name of the annotation. - - - Retrieves a set of annotation values. For each requested value, returns null if no annotation with the given name exists for the given element. - The set of requested annotations - - - Retrieves the annotations that are directly attached to an element. - The annotations that are directly attached to an element (outside the control of the manager). - The element in question. - - - Gets annotations associated with an element. - The immediate value annotations for the element. - The annotated element. - - - Sets an annotation value for an EDM element. If the value is null, no annotation is added and an existing annotation with the same name is removed. - The annotated element. - Namespace that the annotation belongs to. - Name of the annotation within the namespace. - New annotation to set. - - - Sets a set of annotation values. If a supplied value is null, no annotation is added and an existing annotation with the same name is removed. - The annotations to set - - - Represents a property binding specified as part of an EDM type annotation. - - - Initializes a new instance of the class. - - - Gets or sets the property that is given a value by the annotation. - - - Gets or sets the expression producing the value of the annotation. - - - Represents an EDM type annotation. - - - Initializes a new instance of the class. - - - Adds the property to this type annotation. - The property value binding being added. - - - Gets the value annotations for the properties of the type. - - - Removes the property from this type annotation. - The property value binding being removed. - - - Represents the combination of an EDM annotation with an immediate value and the element to which it is attached. - Type of the annotation value. - - - Initializes a new instance of the EdmTypedDirectValueAnnotationBinding class. - - - Initializes a new instance of the EdmTypedDirectValueAnnotationBinding class. - Element to which the annotation is attached. - - - Initializes a new instance of the EdmTypedDirectValueAnnotationBinding class. - Element to which the annotation is attached. - Value of the annotation - - - Gets or sets the element to which the annotation is attached. - - - Gets the local name of the annotation - - - Gets the namespace Uri of the annotation. - - - Gets or sets the value of this annotation. - - - Represents an EDM value annotation. - - - Initializes a new instance of the class. - - - Gets or sets the expression producing the value of the annotation. - - - Represents an EDM annotation with an immediate value. - - - Initializes a new instance of the class. - - - Gets or sets the qualifier used to discriminate between multiple bindings of the same property or type. - - - Gets or sets the element the annotation applies to. - - - Gets or sets the term bound by the annotation. - - - Represents an EDM type assertion expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the expression for which the type is asserted. - - - Gets or sets the asserted type. - - - Represents an EDM multi-value construction expression. - - - Initializes a new instance of the class. - The constructed element values. - - - Adds the element to this expression. - The element being added. - - - Gets or sets the declared type of the collection. - - - Gets the constructed element values. - - - Gets the kind of this expression. - - - Removes the element from this expression. - The element being removed. - - - Represents an EDM entity set reference expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the referenced entity set. - - - Represents an EDM enumeration member reference expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the referenced enum member. - - - Represents an EDM function application expression. - - - Initializes a new instance of the class. - - - Adds the argument to this function. - The argument being added. - - - Gets or sets the applied function. - - - Gets the arguments to the function. - - - Gets the kind of this expression. - - - Removes the argument from this function. - The argument being removed. - - - Represents an EDM function reference expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the referenced function. - - - Represents an EDM if expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the expression to evaluate if evaluates to false. - - - Gets or sets the expression to evaluate if evaluates to true. - - - Gets or sets the test expression. - - - Represents an EDM type test expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the expression whose type is to be tested. - - - Gets or sets the type to be tested against. - - - Represents an EDM labeled expression. - - - Initializes a new instance of the class. - - - Gets or sets the underlying element expression. - - - Gets the expression kind. - - - Gets or sets the label. - - - Represents an EDM labeled expression reference expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the referenced labeled element. - - - Represents an EDM parameter reference expression. - - - Initializes a new instance of the class. - - - Gets the kind of this expression. - - - Gets or sets the referenced parameter. - - - Represents an EDM path expression. - - - Initializes a new instance of the class. - - - Adds the segment to this path. - The path segment being added. - - - Gets the kind of this expression. - - - Gets the path as a decomposed qualified name. "A.B.C" is { "A", "B", "C" }. - - - Removes the segment from this path. - The path segment being removed. - - - Represents an EDM property constructor specified as part of a EDM record construction expression. - - - Initializes a new instance of the class. - - - Gets or sets the name of the property. - - - Gets or sets the expression for the value of the property. - - - Represents an EDM property reference expression. - - - Initializes a new instance of the class. - - - Gets or sets the expression for the structured value containing the referenced property. - - - Gets the kind of this expression. - - - Gets or sets the referenced property. - - - Represents an EDM record construction expression. - - - Initializes a new instance of the class. - - - Adds the property to this record. - The property being added. - - - Gets or sets the declared type of the record, or null if there is no declared type. - - - Gets the kind of this expression. - - - Gets the constructed property values. - - - Removes the property from this record. - The property being removed. - - - Represents an EDM value term reference expression. - - - Initializes a new instance of the class. - - - Gets or sets the expression for the structured value containing the referenced term property. - - - Gets the kind of this expression. - - - Gets or sets the optional qualifier. - - - Gets or sets the referenced value term. - - - Represents an EDM binary constant. - - - Initializes a new instance of the class. - Type of the integer. - Integer value represented by this value. - - - Initializes a new instance of the class. - Integer value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM boolean constant. - - - Initializes a new instance of the class. - Type of the boolean. - Boolean value represented by this value. - - - Initializes a new instance of the class. - Boolean value represented by this value. - - - Gets the kind of this expression. - - - Gets a value indicating whether the value of this boolean value is true or false. - - - Gets the kind of this value. - - - Represents an EDM collection value. - - - Initializes a new instance of the class. - A reference to a collection type that describes this collection value - The collection of values stored in this collection value - - - Gets the values stored in this collection. - - - Gets the kind of this value. - - - Represents an EDM datetime constant. - - - Initializes a new instance of the class. - Type of the DateTime. - DateTime value represented by this value. - - - Initializes a new instance of the class. - DateTime value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM datetime with offset constant. - - - Initializes a new instance of the class. - Type of the DateTimeOffset. - DateTimeOffset value represented by this value. - - - Initializes a new instance of the class. - DateTimeOffset value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM decimal constant. - - - Initializes a new instance of the class. - Type of the decimal. - Decimal value represented by this value. - - - Initializes a new instance of the class. - Decimal value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM enumeration type value. - - - Initializes a new instance of the class. - A reference to the enumeration type that describes this value. - The enumeration type value. - - - Initializes a new instance of the class. - A reference to the enumeration type that describes this value. - The underlying type value. - - - Gets or sets the underlying type value of the enumeration type. - - - Gets the kind of this value. - - - Represents an EDM floating point constant. - - - Initializes a new instance of the class. - Type of the floating point. - Floating point value represented by this value. - - - Initializes a new instance of the class. - Floating point value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM guid constant. - - - Initializes a new instance of the class. - Type of the integer. - Integer value represented by this value. - - - Initializes a new instance of the class. - Integer value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM integer constant. - - - Initializes a new instance of the class. - Type of the integer. - Integer value represented by this value. - - - Initializes a new instance of the class. - Integer value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM null. - - - Gets the kind of this expression. - - - Singleton null expression instance. - - - Gets the kind of this value. - - - Represents a value of an EDM property. - - - Initializes a new instance of the EdmPropertyValue class. - Name of the property for which this provides a value. - Value of the property. - - - Gets the name of the property for which this provides a value. - - - Gets the property's value. - - - Represents an EDM string constant. - - - Initializes a new instance of the class. - Type of the string. - String value represented by this value. - - - Initializes a new instance of the class. - String value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM structured value. - - - Initializes a new instance of the EdmStructuredValue class. - Type that describes this value. - Child values of this value. - - - Retrieves the value corresponding to the given property name. Returns null if no such value exists. - The requested value, or null if no such value exists. - The property that describes the value being found. - - - Gets the property values of this structured value. - - - Gets the kind of this value. - - - Represents an EDM time constant. - - - Initializes a new instance of the class. - Type of the Time. - Time value represented by this value. - - - Initializes a new instance of the class. - Time value represented by this value. - - - Gets the kind of this expression. - - - Gets the definition of this value. - - - Gets the kind of this value. - - - Represents an EDM value. - - - Initializes a new instance of the EdmValue class. - Type of the value. - - - Gets {insert text here}. - - - Gets the type of this value. - - - Gets the kind of this value. - - - Represents a reportable error in EDM. - - - Creates a new instance of the class. - The location where the error occurred. - An integer code representing the error. - A human readable message describing the error. - - - Gets an integer code representing the error. - The code representing the error. - - - Gets the location of the error in the file in which it occurred. - The location of the error in the file in which it occurred. - - - Gets a human readable string describing the error. - A human readable string describing the error. - - - Gets a string representation of the error. - A string representation of the error. - - - EdmLib validation error codes - - - - - - References to EDM stream type are not supported before version 3.0. - - - References to EDM spatial types are not supported before version 3.0. - - - An exception was thrown by the underlying xml reader. - - - - - - - - - - - - - - - - - - - - - - - - An XML attribute or element representing EDM type is missing. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The value of the property must not be null. - - - An object with an interface kind property does not implement the interface corresponding to the value of that property. For example this error will be reported for an object that implements interface with kind property reporting .Entity, but does not implement interface. - - - The value of an interface kind property is not semantically valid. A semantically valid model must not contain elements of kind 'None'. - - - An enumeration property must not contain null elements. - - - The value of the enum type property is out of range. - - - If property P1 is a navigation property and P2 is its parnter, then partner property of P2 must be P1. - - - A chain of base types is cyclic. - - - - - - - - - An error occured processing the OnDelete element - - - No complex type with that name exists. - - - - - - Function import specifies an entity set expression which is not supported in this context. Function import entity set expression can be either an entity set reference or a path starting with a function import parameter and traversing navigation properties. - - - - - - - - - - - - Invalid multiplicty of the principal end of a navigation. - - - - - - Invalid multiplicty of the dependent end of a navigation. - - - Open types are supported only in version 1.2 and after version 2.0 - - - Vocabulary annotations are not supported before EDM 3.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A composable function import must have return type. - - - - - - - - - Nullable complex Type not supported in version 1.0 and 2.0. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Could not find a function with this name. - - - - - - - - - - - - The principal end of a referential constraint must be one of the ends of the association that defined the referential constraint. - - - - - - - - - - - - Value terms are not supported before EDM 3.0 - - - - - - - - - - - - - - - - - - Unsupported function import parameter type. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Binary value is invalid. - - - Floating point value is invalid. - - - DateTime value is invalid. - - - DateTimeOffset value is invalid. - - - Decimal value is invalid. - - - Guid value is invalid. - - - The type kind None is not semantically valid. A semantically valid model must not contain elements of type kind None. - - - - - - - - - - - - The IsType expression is invalid because it does not have 1 element. - - - The type name is not fully qualified and not a primitive. - - - The term name is not fully qualified. - - - No model was parsed because no XmlReaders were provided. - - - Model could not be parsed because one of the XmlReaders was null. - - - IsMaxMaxLength cannot be true if MaxLength is non-null. - - - ImmediateValueAnnotation is invalid as an element annotation. - - - The LabeledElement expression is invalid because it does not have 1 element. - - - Could not find a LabeledElement with that name - - - Could not find a enum member with that name - - - The AssertType expression is invalid because it does not have 1 element. - - - Could not find a Parameter with that name - - - A navigation property with = true must point to an optional target. - - - If a navigation property has = true and the target entity type is the same as the declaring type of the property, then the multiplicity of the source of navigation is Zero-Or-One. - - - If a navigation property has = true and the target entity type is defferent than the declaring type of the property, then the multiplicity of the source of navigation is One. - - - Navigation properties with setting are not supported before version 3.0. - - - The annotation target path cannot possibly refer to an annotable element. - - - A nullable type is not valid if a non-nullable type is required. - - - The expression is a primitive constant, and cannot be valid for an non-primitive type. - - - The primitive type is not valid for the requested type. - - - Null is not valid in a non nullable expression. - - - The expression is not valid for the asserted type. - - - A collection expression is not valid for a non-collection type. - - - A record expression is not valid for a non-structured type. - - - The record expression does not have all of the properties required for the specified type. - - - The record expression's type is not open, but the record expression has extra properties. - - - Target has multiple annotations with the same term and same qualifier. - - - Function application has wrong number of arguments for the function being applied. - - - Is it invalid to have multiple using statements with the same alias in a single schema element. - - - A model cannot be serialized to CSDL if it has references to types without fully qualified names. - - - The model could not be serialized because multiple schemas were produced and only a single output stream was found. - - - The Edmx version is not valid. - - - The EdmVersion is not valid. - - - Nothing was written because no schemas were produced. - - - Model has multiple entity containers with the same name. - - - The container name of a container element must be the full name of the container entity container. - - - A primitive constant expression is not valid for a non-primitive type. - - - The value of the integer constant is out of range for the asserted type. - - - The length of the string constant is too large for the asserted type. - - - The length of the binary constant is too large for the asserted type. - - - None is not a valid mode for a function import parameter. - - - A type without other errors must not have kind of none. - - - A primitive type without other errors must not have kind of none. - - - A property without other errors must not have kind of none. - - - A term without other errors must not have kind of none. - - - A schema element without other errors must not have kind of none. - - - An entity container element without other errors must not have kind of none. - - - A binary value must have content. - - - There can only be a single navigation property mapping with containment that targets a particular entity set. - - - The navigation properties partner does not point back to the correct type. - - - An entity set can only have one navigation property with containment. - - - If a navigation property is traversed from an entity set, and then it's partner is traversed from the target of the first mapping, the destination should be the originating entity set. - - - There can only be a single mapping from a given EntitySet with a particular navigation property. - - - An entity set must have a mapping for all of the navigation properties in its element type. - - - Type annotation does not have a property binding for all required properties. - - - Type annotation has a property binding for a non-existant property and its type is not open. - - - Time value is invalid. - - - The primitive type is invalid. - - - An Enum type must have an underlying type of integer. - - - Could not find a term with this name. - - - The principal properties of a referential constraint must match the key of the referential constraint. - - - A direct value annotation with the same name and namespace already exists. - - - AssociationSetEnd cannot infer an entity set because no set exists of the given type. - - - AssociationSetEnd cannot infer an entity set because more than one set exists of the given type. - - - Invalid entity set path. - - - Invalid enum member path. - - - An annotation qualifier must be a simple name. - - - Enum type could not be resolved. - - - Could not find a target with this name. - - - Represents a collection of validation methods. - - - Validates the and all of its properties given certain version. - True if model is valid, otherwise false. - The root of the model to be validated. - The custom rule set to validate against. - The errors encountered while validating the model. - - - Validates the and all of its properties using the current version of the model. If the model has no version, is used. - True if model is valid, otherwise false. - The root of the model to be validated. - The errors encountered while validating the model. - - - Validates the and all of its properties given certain version. - True if model is valid, otherwise false. - The root of the model to be validated. - The version of EDM to validate against. - The errors encountered while validating the model. - - - Collection of extension methods to assert that an expression is of the required type. - - - Determines if the type of an expression is compatible with the provided type - A value indicating whether the expression is valid for the given type or not. - The expression to assert the type of. - The type to assert the expression as. - Errors produced if the expression does not match the specified type. - - - Defines an object as a location of itself. - - - Gets the object. - - - Gets a string representation of the location. - A string representation of the location. - - - Specifies a context that records errors reported by validation rules. - - - Adds an error with the validation context. - The location of the error. - The value representing the error. - The message text describing the error. - - - Adds an error with the validation context. - The error to register. - - - Method returns true if the element is known to have structural errors associated with it. - True if the element has structural errors associated with it. - The element to test. - - - Gets the model being validated. - The model being validated. - - - Contains IsBad() and Errors() extension methods. - - - Gets the errors, if any, that belong to this element or elements that this element contains. For example errors for a structural type include the errors of the type itself and errors of its declared properties. The method does not analyze elements referenced by this element. For example errors of a property do not include errors from its type. - Any errors that belong to this element or elements that element contains. - Reference to the calling object. - - - Returns true if this element contains errors returned by the <see cref="M:Microsoft.Data.Edm.Validation.ValidationExtensionMethods.Errors(Microsoft.Data.Edm.IEdmElement)" /> method. - This element is an invalid element. - Reference to the calling object. - - - Gets the errors, if any, that belong to this type reference or its definition. - Any errors that belong to this type reference or its definition. - The type reference. - - - Represents a semantic validation rule. - - - Creates a new instance of the class. - - - Represents a validation rule that is valid for a specific type. - The type that the rule is valid for. - - - - Built in Edm validation rules - - - Validates that the max length of a binary type is not negative. - - - Validates that IsMaxMaxLength cannot be true if MaxLength is non-null. - - - Validates that all properties of a collection expression are of the correct type. - - - Validates that a complex type is not abstract. - - - Validates that a complex type does not inherit. - - - Validates that if a function import is composable, it must have a return type. - - - Validates that the precision is between 0 and the max precision of the decimal type. - - - Validates that the scale is between 0 and the precision of the decimal type. - - - Validates that no direct value annotations share the same name and namespace. - - - The container name of an entity container element must match the full name of the containing entity container. - - - Validates that there are no duplicate names in an entity container. - - - An entity container element without other errors must not have kind of none. - - - Validates that the entity type wrapped in this entity reference can be found through the model being validated. - - - Validates that an entity set can only have a single navigation property targetting it that has Contains set to true. - - - Validates that the entity type of an entity set can be found from the model being validated. - - - Validates that if a navigation property is traversed to another entity set, and then the navigation properties partner is traversed, the destination will be the source entity set. - - - Validates that no navigation property is mapped to two different entity sets. - - - - Validates that there are not duplicate properties in an entity key. - - - Validates that all parts of an entity key are scalar. - - - Validates that no part of an entity key is a binary primitive type. - - - Validates that a key is not defined if there is already a key in the base type. - - - Validates that no part of an entity key is nullable. - - - Validates that the entity type has a key. - - - Validates that all properties in the key of an entity blong to that entity. - - - - Raises an error if the underlying type of an enum type is not an integer type. - - - Validates that there are not duplicate enum members in an enum. - - - Raises an error if an enum type is found. - - - Validates the types of a function application are correct. - - - Validates that a function does not have multiple parameters with the same name. - - - Validates that if a function is bindable, it must have parameters. - - - Validates that if a function is composable, it is not also sideeffecting. - - - Validates that the entity set of a function import is defined using a path or an entity set reference expression. - - - - Validates that a function is not bindable. - - - Validates that a function import is not composable. - - - Validates that a function import is not sideeffecting. - - - Validates that no function import parameters have mode of none. - - - Validates that the type of a function imports parameter is correct. - - - - Validates that a function import has an allowed return type - - - - Validates that no function parameters are output parameters. - - - - Validates that an if expression has a boolean condition. - - - Validates that an immediate value annotation that is flagged to be serialized as an element can be serialized safely. - - - Validates that an immediate value annotation has a name and a namespace. - - - Validates that there are not duplicate properties in an entity key. - - - Validates every schema element in the current model is unique across all referenced models. - - - Validates every schema element in the current model (except for entity containers) is unique across all referenced models. - - - Validates that an element name matches the allowed pattern of names according to the CSDL spec. - - - Validates that an element name is not too long according to the CSDL spec. - - - Validates that a name is not empty or whitespace. - - - Validates that is not set prior to V3. - - - Validates that the type of a navigation property corresponds to the other end of the association and the multiplicity of the other end. - - - Validates that if the dependent properties are equivalent to the key of the dependent end, the multiplicity of the dependent end cannot be 1 Validates multiplicity of the dependent end according to the following rules: 0..1, 1 - if dependent properties represent the dependent end key. * - if dependent properties don't represent the dependent end key. - - - Validates that all dependent properties of a navigation property belong to the dependent entity type. - - - Validates that the dependent properties of a navigation property contain no duplicates. - - - Validates that the navigation property does not have both a multiplicity of many and an OnDelete operation. - - - Validates that only one end of an association has an OnDelete operation. - - - Validates that all dependent properties are a subset of the dependent entity types key. - - - Validates that the target of a navigation property's partner is the declaring type of the original. - - - Validates multiplicity of the principal end: 0..1 - if some dependent properties are nullable, 1 - if some dependent properties are not nullable. * - not allowed. - - - Validates that each pair of properties between the dependent properties and the principal ends key are of the same type. - - - Validates that if a navigation property has = true and the target entity type is defferent than the declaring type of the property, then the multiplicity of the source of navigation is One. - - - Validates that if a navigation property has = true and the target entity type is the same as the declaring type of the property, then the multiplicity of the source of navigation is Zero-Or-One. This depends on there being a targetting cycle. Because of the rule , we know that either this is always true, or there will be an error - - - Validates that if a navigation property has = true and the target entity type is the same as the declaring type of the property, then the multiplicity of the target of navigation is 0..1 or Many. This depends on there being a targetting cycle. Because of the rule , we know that either this is always true, or there will be an error - - - Open types are supported only in version 1.2 and after version 2.0. - - - A primtive type without other errors must not have kind of none. - - - Validates that if a primitive value declares a type, the value is acceptable for the type. - - - A property without other errors must not have kind of none. - - - Validates that the value of a property value binding is the correct type. - - - Validates that if a value record expression declares a type, the property types are correct. - - - Validates that a row type does not have a base type. - - - Validates that a row type contains at least one property. - - - A schema element without other errors must not have kind of none. - - - Validates that an element namespace matches the allowed pattern of namespaces according to the CSDL spec. - - - Validates that an element namespace is not too long according to the CSDL spec. - - - Validates that an element namespace is not empty or whitespace. - - - Validates that an element namespace is not a reserved system namespace. - - - References to EDM spatial types are not supported before version 3.0. - - - References to EDM stream type are not supported before version 3.0. - - - Validates that the max length of a string is not negative. - - - Validates that IsMaxMaxLength cannot be true if MaxLength is non-null. - - - Validates that the property is of an allowed type. - - - Validates that if the concurrency mode of a property is fixed, the type is primitive. - - - Validates that any property with a complex type is not nullable. - - - Validates that the base type of a complex type is complex, and the base type of an entity type is an entity. - - - Validates that the base type of a structured type can be found from the model being validated. - - - Validates that a type does not have a property with the same name as that type. - - - Validates that the declaring type of a property contains that property. - - - Validates that there are not duplicate properties in a type. - - - Validates that the precision is between 0 and the max precision of the temporal type. - - - A term without other errors must not have kind of none. - - - Validates that a type annotation implements its term type properly. - - - Validates that a vocabulary annotations term can be found through the model containing the annotation. - - - A type without other errors must not have kind of none. - - - Validates that a type reference refers to a type that can be found through the model being validated. - - - Validates that if a value annotation declares a type, the expression for that annotation has the correct type. - - - Validates that a vocabulary annotations term can be found through the model containing the annotation. - - - Value terms are not supported before EDM 3.0. - - - Validates that there are no annotations that share the same term and qualifier. - - - Validates that a vocabulary annotations target can be found through the model containing the annotation. - - - Qualifier must be simple name. - - - Vocabulary annotations are not supported before EDM 3.0. - - - Provides a set of rules to run during validation. - - - Creates a new instance of the class. - The rules to be contained in this ruleset. - - - Initializes a new instance of the ValidationRuleSet class. - Ruleset whose rules should be contained in this set. - Additional rules to add to the set. - - - Gets the default validation ruleset for the given version. - The set of rules to validate that the model conforms to the given version. - The EDM version being validated. - - - Gets all of the rules in this ruleset. - All of the rules in this ruleset. - - - Gets all of the rules in this ruleset. - All of the rules in this ruleset. - - - Defines Edm values - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value implementing . - - - Represents a value with an unknown or error kind. - - - Represents an EDM binary value. - - - Gets the definition of this binary value. - - - Represents an EDM boolean value. - - - Gets a value indicating whether the value of this boolean value is true or false. - - - Represents an EDM collection value. - - - Gets the values stored in this collection. - - - Represents an EDM datetime with offset value. - - - Gets the definition of this value. - - - Represents an EDM datetime value. - - - Gets the definition of this datetime value. - - - Represents an EDM decimal value. - - - Gets the definition of this decimal value. - - - Represents a lazily computed value. - - - Gets the data stored in this value. - - - Represents an EDM enumeration type value. - - - Gets the underlying type value of the enumeration type. - - - Represents an EDM floating point value. - - - Gets the definition of this floating value. - - - Represents an EDM integer value. - - - Gets the definition of this guid value. - - - Represents an EDM integer value. - - - Gets the definition of this integer value. - - - - - Represents a value of an EDM property. - - - Gets the name of the property this value is associated with. - - - Represents an EDM string value. - - - Gets the definition of this string value. - - - Represents an EDM structured value. - - - Finds the value corresponding to the provided property name. - The found property, or null if no property was found. - Property to find the value of. - - - Gets the property values of this structured value. - - - Represents an EDM time value. - - - Gets the definition of this time value. - - - Represents an EDM value. - - - Gets the type of this value. - - - Gets the kind of this value. - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.dll b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.dll deleted file mode 100644 index d51816ddb1c17..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.xml b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.xml deleted file mode 100644 index 53df6a6a0ef63..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/Microsoft.Data.OData.xml +++ /dev/null @@ -1,2152 +0,0 @@ - - - - Microsoft.Data.OData - - - - Represents an interface for synchronous OData request messages. - - - Returns a value of an HTTP header. - The value of the HTTP header, or null if no such header was present on the message. - The name of the header to get. - - - Gets the stream backing for this message. - The stream backing for this message. - - - Gets an enumerable over all the headers for this message. - An enumerable over all the headers for this message. - - - Gets or sets the HTTP method used for this request message. - The HTTP method used for this request message. - - - Sets the value of an HTTP header. - The name of the header to set. - The value of the HTTP header or 'null' if the header should be removed. - - - Gets or sets the request URL for this request message. - The request URL for this request message. - - - Represents an interface for asynchronous OData request messages. - - - Asynchronously get the stream backing for this message. - The stream for this message. - - - Represents an interface for synchronous OData response messages. - - - Returns a value of an HTTP header. - The value of the HTTP header, or null if no such header was present on the message. - The name of the header to get. - - - Gets the stream backing for this message. - The stream backing for this message. - - - Gets an enumerable over all the headers for this message. - An enumerable over all the headers for this message. - - - Sets the value of an HTTP header. - The name of the header to set. - The value of the HTTP header or 'null' if the header should be removed. - - - Gets or sets the result status code of the response message. - The result status code of the response message. - - - Represents an interface for asynchronous OData response messages. - - - Asynchronously get the stream backing for this message. - The stream backing for this message. - - - Supports custom resolution of URLs found in the payload. - - - Implements a custom URL resolution scheme. This method returns null if no custom resolution is desired. If the method returns a non-null URL that value will be used without further validation. - An instance that reflects the custom resolution of the method arguments into a URL or null if no custom resolution is desired; in that case the default resolution is used. - The (optional) base URI to use for the resolution. - The URI read from the payload. - - - Represents an OData action. - - - Creates a new instance of the class. - - - Represents the base class for all annotatable types in OData library. - - - Creates a new instance of the class. - - - Gets or sets the annotation by type. - The annotation of type T or null if not present. - The type of the annotation. - - - Sets an annotation of type T. - The annotation to set. - The type of the annotation. - - - Represents an association link. - - - Creates a new instance of the class. - - - Gets or sets the name of the association link. - The name of the associate link. - - - Gets or sets the URI representing the Unified Resource Locator (URL) of the link. - The URI representing the Unified Resource Locator (URL) of the link. - - - Displays a message representing an operation in a batch request. - - - Returns a value of an HTTP header of this operation. - The value of the HTTP header, or null if no such header was present on the message. - The name of the header to get. - - - Gets the stream backing for this message. - The stream backing for this message. - - - Asynchronously get the stream backing for this message. - The stream backing for this message. - - - Gets an enumerable over all the headers for this message. - An enumerable over all the headers for this message. - - - Gets the HTTP method used for this request message. - The HTTP method used for this request message. - - - Implements a custom URL resolution scheme. - An instance that reflects the custom resolution of the method arguments into a URL or null if no custom resolution is desired; in that case the default resolution is used. - The (optional) base URI to use for the resolution. - The URI read from the payload. - - - Sets the value of an HTTP header of this operation. - The name of the header to set. - The value of the HTTP header or 'null' if the header should be removed. - - - Gets or sets the request URL for this request message. - The request URL for this request message. - - - Displays a message representing an operation in a batch response. - - - Returns a value of an HTTP header of this operation. - The value of the HTTP header, or null if no such header was present on the message. - The name of the header to get. - - - Gets the stream backing for this message. - The stream backing for this message. - - - Asynchronously get the stream backing for this message. - The stream backing for this message. - - - Gets an enumerable over all the headers for this message. - An enumerable over all the headers for this message. - - - Method to implement a custom URL resolution scheme. This method returns null if not custom resolution is desired. If the method returns a non-null URL that value will be used without further validation. - A instance that reflects the custom resolution of the method arguments into a URL or null if no custom resolution is desired; in that case the default resolution is used. - The (optional) base URI to use for the resolution. - The URI read from the payload. - - - Sets the value of an HTTP header of this operation. - The name of the header to set. - The value of the HTTP header or 'null' if the header should be removed. - - - Gets or sets the result status code of the response message. - The result status code of the response message. - - - Represents a class for reading OData batch messages; also verifies the proper sequence of read calls on the reader. - - - Returns an for reading the content of a batch operation. - A request message for reading the content of a batch operation. - - - Asynchronously returns an for reading the content of a batch operation. - A task that when completed returns a request message for reading the content of a batch operation. - - - Returns an for reading the content of a batch operation. - A response message for reading the content of a batch operation. - - - Asynchronously returns an for reading the content of a batch operation. - A task that when completed returns a response message for reading the content of a batch operation. - - - Reads the next part from the batch message payload. - true if more items were read; otherwise false. - - - Asynchronously reads the next part from the batch message payload. - A task that when completed indicates whether more items were read. - - - The current state of the batch reader. - - - Enumeration with all the states the batch reader can be in. - - - The state the batch reader is in after having been created. - - - The batch reader detected an operation. - - - The batch reader detected the start of a change set. - - - The batch reader completed reading a change set. - - - The batch reader completed reading the batch payload. - - - The batch reader encountered an error reading the batch payload. - - - Writes OData batch messages; also verifies the proper sequence of write calls on the writer. - - - Creates an for writing an operation of a batch request. - The message that can be used to write the request operation. - The Http method to be used for this request operation. - The Uri to be used for this request operation. - - - Creates a message for asynchronously writing an operation of a batch request. - The message that can be used to asynchronously write the request operation. - The HTTP method to be used for this request operation. - The URI to be used for this request operation. - - - Creates a message for writing an operation of a batch response. - The message that can be used to write the response operation. - - - Asynchronously creates an for writing an operation of a batch response. - A task that when completed returns the newly created operation response message. - - - Flushes the write buffer to the underlying stream. - - - Flushes the write buffer to the underlying stream asynchronously. - A task instance that represents the asynchronous operation. - - - Ends a batch; can only be called after WriteStartBatch has been called and if no other active changeset or operation exist. - - - Asynchronously ends a batch; can only be called after WriteStartBatch has been called and if no other active change set or operation exist. - A task instance that represents the asynchronous write operation. - - - Ends an active changeset; this can only be called after WriteStartChangeset and only once for each changeset. - - - Asynchronously ends an active change set; this can only be called after WriteStartChangeset and only once for each change set. - A task instance that represents the asynchronous write operation. - - - Starts a new batch; can be only called once and as first call. - - - Asynchronously starts a new batch; can be only called once and as first call. - A task instance that represents the asynchronous write operation. - - - Starts a new changeset; can only be called after WriteStartBatch and if no other active operation or changeset exists. - - - Asynchronously starts a new change set; can only be called after WriteStartBatch and if no other active operation or change set exists. - A task instance that represents the asynchronous write operation. - - - Represents the base class for OData collection readers. - - - Creates a new instance of the class. - - - Gets the most recent item that has been read. - The most recent item that has been read. - - - Reads the next item from the message payload. - True if more items were read; otherwise false. - - - Asynchronously reads the next item from the message payload. - A task that when completed indicates whether more items were read. - - - Gets or sets the current state of the reader. - The current state of the reader. - - - Enumerates all the possible states of . - - - The reader is at the start; nothing has been read yet. - - - The reader has started reading and is reading the start element of the collection wrapper. - - - The reader read an item from the collection. - - - The reader has finished reading and is reading the end element of the collection wrapper. - - - The reader has thrown an exception; nothing can be read from the reader anymore. - - - The reader has completed; nothing can be read anymore. - - - OData representation of a top-level collection. - - - Initializes a new instance of the class. - - - The name of the collection (ATOM only). - - - OData representation of a Collection. - - - Initializes a new instance of the class. - - - The items in the bag value. - - - The type of the collection value. - - - Represents the base class for OData collection writers. - - - Creates a new instance of the class. - - - Flushes the write buffer to the underlying stream. - - - Flushes the write buffer to the underlying stream asynchronously. - A task instance that represents the asynchronous operation. - - - Finishes writing a collection. - - - Asynchronously finish writing a collection. - A task instance that represents the asynchronous write operation. - - - Starts writing an entry. - The collection item to write. - - - Asynchronously start writing a collection item. - A task instance that represents the asynchronous write operation. - The collection item to write. - - - Start writing a collection. - The representing the collection. - - - Asynchronously start writing a collection. - A task instance that represents the asynchronous write operation. - The representing the collection. - - - Represents the OData complex value. - - - Creates a new instance of the class. - - - Gets or sets the properties and values of the complex value. - The properties and values of the complex value. - - - Gets or sets the type of the complex value. - The type of the complex value. - - - Constant values used by the OData or HTTP protocol or OData library. - - - Name of the HTTP content-ID header. - - - Name of the HTTP content type header. - - - Name of the OData 'DataServiceVersion' HTTP header. - - - HTTP method name for DELETE requests. - - - HTTP method name for GET requests. - - - Custom HTTP method name for MERGE requests. - - - HTTP method name for PATCH requests. - - - HTTP method name for POST requests. - - - HTTP method name for PUT requests. - - - Exception type representing exception when Content-Type of a message is not supported. - - - Creates a new instance of the class. - - - Creates a new instance of the class from the specified SerializationInfo and StreamingContext instances. - A SerializationInfo containing the information required to serialize the new ODataException. - A StreamingContext containing the source of the serialized stream associated with the new ODataException. - - - Creates a new instance of the class. - Plain text error message for this exception. - - - Creates a new instance of the class. - Plain text error message for this exception. - Exception that caused this exception to be thrown. - - - Represents an OData entity reference link. - - - Creates a new instance of the class. - - - Gets or sets the URI representing the URL of the referenced entity. - The URI representing the URL of the referenced entity. - - - Represents a collection of entity reference links. - - - Creates a new instance of the class. - - - Represents the optional inline count of the $links collection. - - - Gets or sets the enumerable of instances representing the links of the referenced entities. - The enumerable of instances. - - - Represents the optional next link of the $links collection. - - - Represents a single entity. - - - Creates a new instance of the class. - - - Gets or sets the entity actions. - The entity actions. - - - Gets or sets the association links. - The association links. - - - Gets or sets the link used to edit the entry. - The link used to edit the entry. - - - Gets or sets the entry ETag. - The entry ETag. - - - Gets or sets the entity functions. - The entity functions. - - - Gets or sets the Entry identifier. - The Entry identifier. - - - Gets or sets the default media resource of the media link entry. - The default media resource of the media link entry. - - - Gets or sets the entry properties. - The entry properties. - - - Gets or sets a link that can be used to read the entry. - The link that can be used to read the entry. - - - Gets or sets the type name of the entry. - The type name of the entry. - - - Represents an error payload. - - - Creates a new instance of the class. - - - Gets or sets the error code to be used in payloads. - The error code to be used in payloads. - - - Gets or sets the implementation specific debugging information to help determine the cause of the error. - The implementation specific debugging information. - - - Gets or sets the error message. - The error message. - - - Gets or sets the language for the exception Message. - The language for the exception Message. - - - Represents an in-stream error parsed when reading a payload. - - - Creates a new instance of the class with default values. - - - Creates a new instance of the class with an object. - The instance representing the error read from the payload. - - - Creates a new instance of the class with an error message. - The plain text error message for this exception. - - - Creates a new instance of the class with an error message and an object. - The plain text error message for this exception. - The instance representing the error read from the payload. - - - Creates a new instance of the class with an error message and an inner exception. - The plain text error message for this exception. - The inner exception that is the cause of this exception to be thrown. - - - Creates a new instance of the class with an error message, an inner exception, and an object. - The plain text error message for this exception. - The inner exception that is the cause of this exception to be thrown. - The instance representing the error read from the payload. - - - Gets or sets the instance representing the error read from the payload. - The instance representing the error read from the payload. - - - Represents an exception in the OData library. - - - Creates a new instance of the class with default values. - - - Creates a new instance of the class from the specified and instances. - A containing the information required to serialize the new . - A containing the source of the serialized stream associated with the new . - - - Creates a new instance of the class with an error message. - The plain text error message for this exception. - - - Creates a new instance of the class with an error message and an inner exception. - The plain text error message for this exception. - The inner exception that is the cause of this exception to be thrown. - - - Describes a collection of entities. - - - Creates a new instance of the class. - - - Gets or sets the number of items in the feed. - The number of items in the feed. - - - Gets or sets the URI that identifies the entity set represented by the feed. - The URI that identifies the entity set represented by the feed. - - - Gets or sets the URI representing the next page link. - The URI representing the next page link. - - - Enumerates the format type in connection to processing OData payloads. - - - Initializes a new instance of the class. - - - ATOM format; we also use this for all Xml based formats (if ATOM can't be used). - - - The batch format instance. - - - JSON format - - - The metadata format instance. - - - RAW format; used for raw values. - - - Represents an OData function. - - - Creates a new instance of the class. - - - Contains properties used to implement specific debugging information to help determine the cause of the error. - - - Initializes a new instance of the class with default values. - - - Initializes a new instance of the class with exception object. - The used to create the inner error. - - - Gets or sets the nested implementation specific debugging information. - The nested implementation specific debugging information. - - - Gets or sets the error message. - The error message. - - - Gets or sets the stack trace for this error. - The stack trace for this error. - - - Gets or sets the type name of this error, for example, the type name of an exception. - The type name of this error. - - - Represents the base class for and classes. - - - Initializes a new instance of the class. - - - Quotas to use for limiting resource consumption when reading or writing OData messages. - - - Constructor to create default message quotas for OData readers and writers. - - - Copy constructor. - The instance to copy. - - - The maximum number of entity mapping attributes to be found for an entity type (on the type itself and all its base types). - - - The maximum depth of nesting allowed when reading or writing recursive payloads. - - - The maximum number of operations allowed in a single changeset. - - - The maximum number of top level query operations and changesets allowed in a single batch. - - - The maximum number of bytes that should be read from the message. - - - Represents the reader class used to read all OData payloads (entries, feeds, metadata documents, service documents, and so on). - - - Creates a new for the given request message. - The request message for which to create the reader. - - - Creates a new for the given request message and message reader settings. - The request message for which to create the reader. - The message reader settings to use for reading the message payload. - - - Creates a new for the given request message and message reader settings. - The request message for which to create the reader. - The message reader settings to use for reading the message payload. - The metadata provider to use. - - - Creates a new for the given response message. - The response message for which to create the reader. - - - Creates a new for the given response message and message reader settings. - The response message for which to create the reader. - The message reader settings to use for reading the message payload. - - - Creates a new for the given response message and message reader settings. - The response message for which to create the reader. - The message reader settings to use for reading the message payload. - The metadata provider to use. - - - Creates an to read a batch of requests or responses. - The created batch reader. - - - Asynchronously creates an to read a batch of requests or responses. - A running task for the created batch reader. - - - Creates an to read a collection of primitive or complex values (as result of a service operation invocation). - The created collection reader. - - - Creates an to read a collection of primitive or complex values (as result of a service operation invocation). - The created collection reader. - The expected resource type for the items in the collection. - - - Asynchronously creates an to read a collection of primitive or complex values (as result of a service operation invocation). - A running task for the created collection reader. - - - - Creates an to read an entry. - The created reader. - - - Creates an to read an entry. - The created reader. - The expected entity type for the entry to be read. - - - Asynchronously creates an to read an entry. - A running task for the created reader. - - - - Creates an to read a feed. - The created reader. - - - Creates an to read a feed. - The created reader. - The expected base resource type for the entities in the feed. - - - Asynchronously creates an to read a feed. - A running task for the created reader. - - - - - - Determines the potential payload kinds and formats of the payload being read and returns it. - The set of potential payload kinds and formats for the payload being read by this reader. - - - Determines the potential payload kinds and formats of the payload being read and returns it. - The set of potential payload kinds and formats for the payload being read by this reader. - - - - implementation to cleanup unmanaged resources of the reader. - - - Reads a singleton result of a $links query (entity reference link) as the message payload. - The entity reference link read from the message payload. - - - Asynchronously reads a singleton result of a $links query (entity reference link) as the message payload. - A running task representing the reading of the entity reference link. - - - Reads the result of a $links query (entity reference links) as the message payload. - The entity reference links read as message payload. - - - Asynchronously reads the result of a $links query as the message payload. - A task representing the asynchronous reading of the entity reference links. - - - Reads an as the message payload. - The read from the message payload. - - - Asynchronously reads an as the message payload. - A task representing the asynchronous operation of reading the error. - - - Reads the message body as metadata document. - Returns . - - - Reads an as message payload. - The property read from the payload. - - - Reads an as message payload. - The property read from the payload. - The expected resource type of the property to read. - - - Asynchronously reads an as message payload. - A task representing the asynchronous operation of reading the property. - - - - Reads a service document payload. - The service document read. - - - Asynchronously reads a service document payload. - A task representing the asynchronous operation of reading the service document. - - - Reads a single value as the message body. - The read value. - The expected resource type for the value to be read; null if no expected type is available. - - - - Represents the configuration settings for OData message readers. - - - Initializes a new instance of the class with default values. - - - - Gets or sets the document base URI (used as base for all relative URIs). If this is set, it must be an absolute URI. - The base URI. - - - Gets or sets a value that indicates whether the reader checks for valid XML characters. - true if the reader checks for valid XML characters; otherwise, false. - - - Gets or sets a value that indicates whether the message stream will not be disposed after finishing writing with the message. - true if the message stream will not be disposed after finishing writing with the message; otherwise false. The default value is false. - - - Gets or sets a value that indicates whether not to convert all primitive values to the type specified in the payload. - true if primitive values and report values are not converted; false if all primitive values are converted to the type specified in the payload. The default value is false. - - - - - - - - The maximum OData protocol version the reader should accept and understand. - - - Quotas to use for limiting resource consumption when reading an OData message. - - - The behavior the reader should use when it finds undeclared property. - - - Represents the writer class used to write all OData payloads (entries, feeds, metadata documents, service documents, and so on.). - - - Creates a new for the given request message. - The request message for which to create the writer. - - - Creates a new for the given request message and message writer settings. - The request message for which to create the writer. - The message writer settings to use for writing the message payload. - - - Creates a new for the given request message and message writer settings. - The request message for which to create the writer. - The message writer settings to use for writing the message payload. - The metadata provider to use. - - - Creates a new for the given response message. - The response message for which to create the writer. - - - Creates a new for the given response message and message writer settings. - The response message for which to create the writer. - The message writer settings to use for writing the message payload. - - - Creates a new for the given response message and message writer settings. - The response message for which to create the writer. - The message writer settings to use for writing the message payload. - The metadata provider to use. - - - Creates an to write a batch of requests or responses. - The created batch writer. - - - Asynchronously creates an to write a batch of requests or responses. - A running task for the created batch writer. - - - Creates an to write a collection of primitive or complex values (as result of a service operation invocation). - The created collection writer. - - - Asynchronously creates an to write a collection of primitive or complex values (as result of a service operation invocation). - A running task for the created collection writer. - - - Creates an to write an entry. - The created writer. - - - Asynchronously creates an to write an entry. - A running task for the created writer. - - - Creates an to write a feed. - The created writer. - - - Asynchronously creates an to write a feed. - A running task for the created writer. - - - Creates an to write a parameter payload. - The created parameter writer. - The function import whose parameters will be written. - - - Asynchronously creates an to write a parameter payload. - The created parameter writer. - The function import whose parameters will be written. - - - - implementation to cleanup unmanaged resources of the writer. - - - Writes a singleton result of a $links query as the message payload. - The entity reference link to write as the message payload. - - - Asynchronously writes a singleton result of a $links query as the message payload. - A running task representing the writing of the link. - The link result to write as the message payload. - - - Writes the result of a $links query as the message payload. - The entity reference links to write as message payload. - - - Asynchronously writes the result of a $links query as the message payload. - A task representing the asynchronous writing of the entity reference links. - The entity reference links to write as message payload. - - - Writes an as the message payload. - The error to write. - A flag indicating whether debug information (for example, the inner error from the ) should be included in the payload. This should only be used in debug scenarios. - - - Asynchronously writes an as the message payload. - A task representing the asynchronous operation of writing the error. - The error to write. - A flag indicating whether debug information (for example, the inner error from the ) should be included in the payload. This should only be used in debug scenarios. - - - Writes the metadata document as the message body. - - - Writes an as the message payload. - The property to write. - - - Asynchronously writes an as the message payload. - A task representing the asynchronous operation of writing the property. - The property to write - - - Writes a service document with the specified as the message payload. - The default workspace to write in the service document. - - - Asynchronously writes a service document with the specified as the message payload. - A task representing the asynchronous operation of writing the service document. - The default workspace to write in the service document. - - - Writes a single value as the message body. - The value to write. - - - Asynchronously writes a single value as the message body. - A running task representing the writing of the value. - The value to write. - - - Represents the configuration settings for OData message writers. - - - Initializes a new instance of the class with default settings. - - - - Gets or sets the document base URI which is used as base for all relative URIs. - The document base URI which is used as base for all relative URIs. - - - Gets or sets a value that indicates whether the reader checks for valid XML characters. - true if the reader checks for valid XML characters; otherwise, false. - - - Gets or sets a value that indicates whether the message stream will not be disposed after finishing writing with the message. - true if the message stream will not be disposed after finishing writing with the message; otherwise false. The default value is false. - - - - - - Gets or sets a value to indicate whether the writer uses indentation. - true if the writer uses indentation; otherwise, false. - - - Quotas to use for limiting resource consumption when writing an OData message. - - - Sets the format to be used when writing the payload. This will automatically set a compatible content type header. - The format to use for writing the payload. - - - Sets the acceptable media types and character sets from which the content type will be computed when writing the payload. - The acceptable media types used to determine the content type of the message. This is a comma separated list of content types as specified in RFC 2616, Section 14.1 - The acceptable charsets to use to determine the encoding of the message. This is a comma separated list of charsets as specified in RFC 2616, Section 14.2 - - - Gets or sets the OData protocol version to be used for writing payloads. - The OData protocol version to be used for writing payloads. - - - Represents a single link. - - - Initializes a new instance of the class. - - - Gets or sets a value that indicates whether the navigation link represents a collection or an entry. - true if the navigation link represents a collection; false if the navigation represents an entry. - - - Gets or sets the name of the link. - The name of the link. - - - Gets or sets the URI representing the Unified Resource Locator (URL) of the link. - The URI representing the Unified Resource Locator (URL) of the link. - - - Represents a function or an action. - - - Initializes a new instance of the class. - - - The URI that identifies the or the . - - - Gets or sets the URI to invoke the or the . - The URI to invoke the or the . - - - Gets or sets a human-readable description of the or the . - A human-readable description of the or the . - - - Base class for OData parameter readers. - - - Initializes a new instance of the class. - - - Creates an to read the collection value when the state is ODataParameterReaderState.Collection. - An to read the collection value when the state is ODataParameterReaderState.Collection. - - - Gets the name of the current parameter that is being read. - The name of the current parameter that is being read. - - - Reads the next parameter from the message payload. - true if more items were read; otherwise false. - - - Asynchronously reads the next item from the message payload. - A task that when completed indicates whether more items were read. - - - Gets the current state of the reader. - The current state of the reader. - - - Gets the value of the current parameter that is being read. - The value of the current parameter that is being read. - - - Enumeration of all possible states of an . - - - The reader is at the start; nothing has been read yet. - - - The reader read a primitive or a complex parameter. - - - The reader is reading a collection parameter. - - - The reader has thrown an exception; nothing can be read from the reader anymore. - - - The reader has completed; nothing can be read anymore. - - - Base class for OData collection writers. - - - Initializes a new instance of the class. - - - Creates an to write the value of a collection parameter. - The newly created . - The name of the collection parameter to write. - - - - Flushes the write buffer to the underlying stream. - - - Asynchronously flushes the write buffer to the underlying stream. - A task instance that represents the asynchronous operation. - - - Finish writing a parameter payload. - - - Asynchronously finish writing a parameter payload. - A task instance that represents the asynchronous write operation. - - - Start writing a parameter payload. - - - Asynchronously start writing a parameter payload. - A task instance that represents the asynchronous write operation. - - - Start writing a value parameter. - The name of the parameter to write. - The value of the parameter to write. - - - Asynchronously start writing a value parameter. - A task instance that represents the asynchronous write operation. - The name of the parameter to write. - The value of the parameter to write. - - - Enumerates the different kinds of payloads that ODatLib can write. - - - Specifies a payload kind for writing a feed. - - - Specifies a payload kind for writing an entry. - - - Specifies a payload kind for writing a property. - - - Specifies the payload kind for writing an entity reference link. - - - Specifies the payload kind for writing entity reference links. - - - Specifies a payload kind for writing a raw value. - - - Specifies the payload kind for writing a binary value. - - - Specifies a payload kind for writing a collection. - - - Specifies a payload kind for writing a service document. - - - Specifies a payload kind for writing a metadata document. - - - Specifies a payload kind for writing an error. - - - Specifies the payload kind for writing a batch. - - - Specifies a payload kind for writing a parameter. - - - Specifies an unknown format. - - - Represents the set of information available for payload kind detection. - - - The encoding derived from the content type or the default encoding. - The encoding derived from the content type or the default encoding. - - - The being used for reading the message. - - - The for the payload. - - - The possible payload kinds based on content type negotiation. - - - Represents the result of running payload kind detection for a specified payload kind and format. - - - The format for the detected payload kind. - - - The detected payload kind. - - - Represents a single property of an entry. - - - Initializes a new instance of the class. - - - Gets or sets the property name. - The property name. - - - Gets or sets the property value. - The property value. - - - Represents the base class for OData readers. - - - Initializes a new instance of the class. - - - Gets the most recent that has been read. - The most recent that has been read. - - - Reads the next from the message payload. - true if more items were read; otherwise false. - - - Asynchronously reads the next from the message payload. - A task that when completed indicates whether more items were read. - - - Gets the current state of the reader. - The current state of the reader. - - - Enumeration of all possible states of an . - - - The reader is at the start; nothing has been read yet. - - - The start of a feed has been read. - - - The end of a feed has been read. - - - The start of an entry has been read. - - - The end of an entry has been read. - - - The start of a navigation link has been read. - - - The end of a navigation link has been read. - - - An entity reference link was read. - - - The reader has thrown an exception; nothing can be read from the reader anymore. - - - The reader has completed; nothing can be read anymore. - - - Represents a class that contains collection of information about a resource in a workspace of a data service. - - - Initializes a new instance of the class. - - - Gets or sets the URI representing the Unified Resource Locator (URL) to the collection. - The URI representing the Unified Resource Locator (URL) to the collection. - - - Represents a media resource. - - - Initializes a new instance of the class. - - - Gets or sets the content media type. - The content media type. - - - Gets or sets the edit link for media resource. - The edit link for media resource. - - - Gets or sets the media resource ETag. - The media resource ETag. - - - Gets or sets the read link for media resource. - The read link for media resource. - - - Behavior of readers when reading undeclared property. - - - The default behavior - the reader will fail if it finds a property which is not declared by the model and the type is not open. - - - The reader will skip reading the property if it's not declared by the model. - - - The reader will read and report link properties which are not declared by the model. - - - Represents the utility methods used with the OData library. - - - Checks whether the annotatable has an HttpMethod annotation. - The (non-null) value of the HttpMethod annotation of the annotatable or null if no such annotation exists. - The containing the annotation. - The to check. - - - Checks whether the annotatable has a MIME type annotation. - The (non-null) value of the MIME type annotation of the annotatable or null if no MIME type annotation exists. - The containing the annotation. - The to check. - - - Returns the format used by the message reader for reading the payload. - The format used by the messageReader for reading the payload. - The to get the read format from. - - - Checks whether the entityType has a default stream. - true if the entity type has a default stream; otherwise false. - The containing the annotation. - The to check. - - - Gets the value of IsAlwaysBindable annotation on the functionImport. - The value of the annotation if it exists; false otherwise. - The containing the annotation. - The to get the annotation from. - functionImport - - - Checks whether the entityContainer is the default entity container. - true if the entityContainer is the default container; otherwise false. - The containing the annotation. - The to check. - - - - Loads the supported, OData-specific serializable annotations into their in-memory representations. - The containing the annotations. - The to process. - - - Loads the supported, OData-specific serializable annotations into their in-memory representations. - The containing the annotations. - The to process. - The maximum number of entity mapping attributes to be found for an entity type (on the type itself and all its base types). - - - Loads the supported, OData-specific serializable annotations into their in-memory representations. - The to process. - The maximum number of entity mapping attributes to be found for an entity type (on the type itself and all its base types). - - - Gets the reader behavior for null property value on the specified property. - The behavior to use when reading null value for this property. - The model containing the annotation. - The property to check. - - - - - - Turns the in-memory representations of the supported, OData-specific annotations into their serializable form. - The containing the annotations. - The to process. - - - Adds or removes a default stream to/from the entityType. - The containing the annotation. - The to modify. - true to add a default stream to the entity type; false to remove an existing default stream (if any). - - - Sets the content-type and data service version headers on the message used by the message writer. - The message writer to set the headers for. - The kind of payload to be written with the message writer. - - - Sets the HttpMethod annotation of the annotatable to httpMethod. - The contatining the annotation. - The to modify. - The HttpMethod value to set as annotation value; if null, an existing annotation will be removed. - - - Sets the value of IsAlwaysBindable annotation of the functionImport to isAlwaysBindable - The containing the annotation. - The to set the annotation on. - The value of the annotation to set. - functionImport - - - Adds or removes a default stream to/from the entityContainer. - The containing the annotation. - The to modify. - true to set the entityContainer as the default container; false to remove an existing default container annotation (if any). - - - Sets the MIME type annotation of the annotatable to mimeType. - The containing the annotation. - The to modify. - The MIME type value to set as annotation value; if null, an existing annotation will be removed. - - - Adds a transient annotation to indicate how null values for the specified property should be read. - The containing the annotations. - The to modify. - The new behavior for reading null values for this property. - - - - - Specifies the OData protocol version. - - - The version 1.0. - - - The version 2.0. - - - The version 3.0. - - - Represents the workspace of a data service. - - - Initializes a new instance of the class. - - - Gets or sets the set of collections in the workspace. - The set of collections in the workspace. - - - Represents a base class for OData writers. - - - Initializes a new instance of the class. - - - Flushes the write buffer to the underlying stream. - - - Flushes the write buffer to the underlying stream asynchronously. - A task instance that represents the asynchronous operation. - - - Finishes the writing of a feed, an entry, or a navigation link. - - - Asynchronously finish writing a feed, entry, or navigation link. - A task instance that represents the asynchronous write operation. - - - Writes an entity reference link, which is used to represent binding to an existing resource in a request payload. - The entity reference link to write. - - - Asynchronously writes an entity reference link, which is used to represent binding to an existing resource in a request payload. - A task instance that represents the asynchronous write operation. - The entity reference link to write. - - - Starts the writing of an entry. - The entry or item to write. - - - Starts the writing of a feed. - The feed or collection to write. - - - Starts the writing of a navigation link. - The navigation link to write. - - - Asynchronously start writing an entry. - A task instance that represents the asynchronous write operation. - The entry or item to write. - - - Asynchronously start writing a feed. - A task instance that represents the asynchronous write operation. - The feed or collection to write. - - - Asynchronously start writing a navigation link. - A task instance that represents the asynchronous write operation. - The navigation link to writer. - - - Represents an annotation which stores a list of projected properties for an entry. - - - Initializes a new instance of the class. - The enumeration of projected property names. - - - Annotation which stores the type name to serialize. - - - Initializes a new instance of the class. - - - Gets or sets the type name to serialize, for the annotated item. - The type name to serialize, for the annotated item. - - - Atom metadata description for a categories element (app:categories). - - - Initializes a new instance of the class. - - - Gets or sets the atom category elements inside this categories element. - The atom category elements inside this categories element. - - - Gets or sets a value that indicates whether the list of categories is fixed or an open set. - true if the list of categories is fixed; false if the list of categories is an open set. - - - Gets or sets the URI of the category document. - The URI of the category document. - - - Gets or sets the URI indicating the scheme of the categories without a scheme. - The URI indicating the scheme of the categories without a scheme. - - - Represents an Atom metadata description for a category. - - - Initializes a new instance of the class. - - - Gets or sets a human-readable label for display in user interfaces. - A human-readable label. - - - Gets or sets the URI that indicates the scheme of the category. - The URI that indicates the scheme of the category. - - - Gets or sets the string value identifying the category. - The string value identifying the category. - - - Represents a type for Atom Syndication Format (Atom) entry annotationsAsArray. - - - Initializes a new instance of the class. - - - Gets or sets a collection of authors of an entry. - A collection of authors of an entry. - - - Gets or sets the categories of an entry. - The categories of an entry. - - - The ATOM metadata for the category element which stores the type name of the entry. - - - Gets or sets a collection of contributors of an entry. - A collection of contributors of an entry. - - - Gets or sets an Atom link metadata for the edit link. - An Atom link metadata for the edit link. - - - Gets or sets the collection of all Atom link information except for the self/edit links and the navigation property links. - The collection of all Atom link information except for the self/edit links and the navigation property links. - - - Gets or sets the date and time when the entry was published. - The date and time when the entry was published. - - - Gets or sets the rights text of an entry. - The rights text of an entry. - - - Gets or sets an Atom link metadata for the self link. - An Atom link metadata for the self link. - - - Gets or sets the source of an entry and if the entry was copied from a different stream the property contains the feed metadata of the original feed. - The source of an entry. - - - Gets or sets the summary of the entry. - The summary of the entry. - - - Gets or sets the title of the entry. - The title of the entry. - - - Gets or sets the date and time of last update to the source. - The date and time of last update to the source. - - - Represents a type for Atom Syndication Format (Atom) feed annotationsAsArray. - - - Initializes a new instance of the class. - - - Gets or sets a collection of authors of a feed. - A collection of authors of a feed. - - - Gets or sets the categories of a feed. - The categories of a feed. - - - Gets or sets a collection of contributors of a feed. - A collection of contributors of a feed. - - - Gets or sets the generator of a feed. - The generator of a feed. - - - Gets or sets the URI of the icon for a feed. - The URI of the icon for a feed. - - - Gets or sets the collection of all Atom link information except for the next page and self links. - The collection of all Atom link information except for the next page and self links. - - - Gets or sets the URI for the feed's logo. - The URI for the feed?s logo. - - - The next page link of the feed. This link should point to the next page of results. - - - Gets or sets the rights text of a feed. - The rights text of a feed. - - - Gets or sets the self link of the feed. This link should point to the source of the feed. - The self link of the feed. - - - Gets or sets the identifier for the feed if used as metadata of an Atom:source element. - The identifier for the feed if used as metadata of an Atom:source element. - - - Gets or sets the subtitle of a feed. - The subtitle of a feed. - - - Gets or sets the title of the feed. - The title of the feed. - - - Gets or sets the date and time of last update to the source. - The date and time of last update to the source. - - - Represents an Atom metadata description of a content generator. - - - Initializes a new instance of the class. - - - Gets or sets the human readable name of the generator of the content. - The human readable name of the generator of the content. - - - Gets or sets the (optional) URI describing the generator of the content. - The (optional) URI describing the generator of the content. - - - Gets or sets the (optional) version of the generator. - The (optional) version of the generator. - - - Represents an Atom metadata description for a link. - - - Initializes a new instance of the class. - - - Gets or sets the URI of the link. - The URI of the link. - - - Gets or sets the language tag (for example, en-US) of the resource pointed to by the link. - The language tag of the resource pointed to by the link. - - - Gets or sets a hint at the length of the content returned from the link. - A hint at the length of the content returned from the link. - - - Gets or sets the media type of the data returned by the link. - The media type of the data returned by the link. - - - Gets or sets the link's relation type. - The link’s relation type. - - - Gets or sets a human-readable description of the link. - A human-readable description of the link. - - - Represents an Atom metadata description for a person. - - - Creates a new instance of the class. - - - Gets or sets an email address associated with the person. - An email address associated with the person. - - - Gets or sets the name of the person (required). - The name of the person (required). - - - - Converts a string to an instance. - The instance created for name. - The name used in the person metadata. - - - Gets or sets an IRI associated with the person. - An IRI associated with the person. - - - Represents an Atom metadata description for a collection (in a workspace). - - - Creates a new instance of the class. - - - Gets or sets the accept range of media types for this collection. - The accept range of media types for this collection. - - - Gets or sets the categories for this collection. - The categories for this collection. - - - Gets or sets the title of the collection. - The title of the collection. - - - Represents an Atom metadata for stream reference values. - - - Creates a new instance of the class. - - - Gets or sets an Atom link metadata for the edit link. - An Atom link metadata for the edit link. - - - Gets or sets an Atom link metadata for the self link. - An Atom link metadata for the self link. - - - Represents an Atom metadata description for a text construct (plain text, html or xhtml). - - - Creates a new instance of the class. - - - Gets or sets the kind of the text construct (plain text, html, xhtml). - The kind of the text construct. - - - - Gets or sets the text content. - The text content. - - - Converts a string to an instance. - The instance created for text. - The to convert to an . - - - Specifies the different kinds of text content in Atom metadata. - - - The plain text. - - - The html text. - - - The xhtml text. - - - Represents an Atom metadata description for a workspace. - - - Creates a new instance of the class. - - - Gets or sets the title of the workspace. - The title of the workspace. - - - Represents the Atom-specific extension methods. - - - Determines an extension method to get the for an annotatable association link. - An instance or null if no annotation of that type exists. - The association link to get the annotation from. - - - Determines an extension method to get the for an annotatable entry. - An instance or null if no annotation of that type exists. - The entry instance to get the annotation from. - - - Determines an extension method to get the for an annotatable feed. - An instance or null if no annotation of that type exists. - The feed instance to get the annotation from. - - - Determines an extension method to get the for an annotatable navigation link. - An instance or null if no annotation of that type exists. - The navigation link instance to get the annotation from. - - - Determines an extension method to get the for an annotatable (resource) collection. - An instance or null if no annotation of that type exists. - The (resource) collection to get the annotation from. - - - Determines an extension method to get the for an annotatable workspace. - An instance or null if no annotation of that type exists. - The workspace to get the annotation from. - - - Represents an annotation to hold information for a particular property. - - - Creates a new instance of the class. - - - Defines the behavior for readers when reading property with null value. - - - Represents an enumerable of that new items can be added to. - - - Creates a new instance of the class. - - - Creates a new instance of the class. - An enumerable of used to initialize the instance. This argument must not be null. - - - Adds the mapping to the list of all mappings represented by this class. - The to add to the enumerable represented by this class. - - - Returns an enumerator for the instances in this enumerable. - An enumerator for the instances in this enumerable. - - - Returns a non-generic enumerator for the instances in this enumerable. - A non-generic enumerator for the instances in this enumerable. - - - Behavior of readers when reading property with null value. - - - The default behavior - this means validate the null value against the declared type and then report the null value. - - - This means to not report the value and not validate it against the model. - - - This means to report the value, but not validate it against the model. - - - Class to represent a null value with or without type information for URI paremeters. - - - Initializes a new instance of the class. - - - String representation of the type of this null value. 'null' indicates that no type information was provided. - - - URI Utility methods. - - - Converts the given value to a corresponding CLR type. Expects the value to have already been properly unescaped from an actual Uri. - A CLR object that the value represents. - Value from a Uri to be converted. - Version to be compliant with. - - - Converts the given value to a corresponding CLR type. Expects the value to have already been properly unescaped from an actual Uri. - A CLR object that the value represents. - Value from a Uri to be converted. - Version to be compliant with. - Optional model to perform verification against. - Optional IEdmTypeReference to perform verification against. Callers must provide a model containing this type if it is specified. - - - Converts the given object to a string for use in a Uri. Does not perform any of the escaping that provides. No type verification is used. - A string representation of value for use in a Url. - Value to be converted. - Version to be compliant with. - - - Converts the given object to a string for use in a Uri. Does not perform any of the escaping that provides. Will perform type verification based on the given model if possible. - A string representation of value for use in a Url. - Value to be converted. - Version to be compliant with. - Optional model to perform verification against. - - - Attribute that specifies a custom mapping between properties of an entity type and elements of an entry in an Open Data Protocol (OData) feed returned by the data service.  - - - Creates a new instance of the . - The name of the property, as string, of the entity type that is mapped to the specified property of the feed item. - A value that represents the element in the feed to which to map the property. This value must be set to None if the is not null. - A value that identifies the format of the content to display in the feed. - Boolean value that is true when the property being mapped must appear both in its mapped-to location and in the content section of the feed. - - - Creates an instance of the to map a property to a custom feed element. - The name of the property of the entity type, as string, that is mapped to the specified property in the feed. - The name of the target, as string, in the resulting feed to which the property is mapped. - This parameter, together with , specifies the namespace in which the element exists. - Specifies the namespace URI of the element, as string, specified by the property. - Boolean value that is true when the property being mapped must appear both in its mapped-to location and in the content section of the feed. - - - Gets a Boolean value that indicates whether a property value should be repeated both in the content section of the feed and in the mapped location. - A value that is true when the property is mapped into both locations in the feed; otherwise, false. - - - Gets the name of the property of the syndication item that will be mapped to the specified element of the feed. - String value that contains property name. - - - Gets a string value that, together with , specifies the namespace in which the element exists. - String value that contains the target namespace prefix. - - - Gets a string value that specifies the namespace URI of the element specified by the property. - String that contains the namespace URI. - - - Gets the name of the custom target in the feed to which the property is mapped. - String value with target XML element or attribute. - - - Gets the syndication item in the entry targeted by the mapping. - A value that is the target of the mapping. - - - Gets the type of content of the property mapped by . - A string that identifies the type of content in the feed element. - - - Enumeration type that is used to identify the syndication item element or attribute in the Open Data Protocol (OData) feed to which an entity property is mapped. - - - A custom property element. - - - The atom:email child element of the atom:author element. - - - The atom:name child element of the atom:author element. - - - The atom:uri child element of the atom:author element. - - - The atom:email child element of the atom:contributor element. - - - The atom:name child element of the atom:contributor element. - - - The atom:uri child element of the atom:contributor element. - - - The atom:updated element. - - - The atom:published element. - - - The atom:rights element. - - - The atom:summary element. - - - The atom:title element. - - - The label attribute of the atom:category element. - - - The scheme attribute of the atom:category element. - - - The term attribute of the atom:category element. - - - The href attribute of the atom:link element. - - - The hreflang attribute of the atom:link element. - - - The length attribute of the atom:link element. - - - The rel attribute of the atom:link element. - - - The title attribute of the atom:link element. - - - The type attribute of the atom:link element. - - - Enumeration used to identify text content of syndication item. - - - Plain text content. - - - HTML content. - - - XHTML content. - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.dll b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.dll deleted file mode 100644 index 978cb3fcea32b..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.xml b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.xml deleted file mode 100644 index ad436e88734e1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Dependencies/System.Spatial.xml +++ /dev/null @@ -1,1100 +0,0 @@ - - - - System.Spatial - - - - Coordinate System Reference - - - Default Geography Reference (SRID 4326, WGS84) - - - Default Geometry Reference - - - The coordinate system ID according to the EPSG, or NULL if this is not an EPSG coordinate system. - - - Equals overload - True if equal - The other CoordinateSystem - - - Equals overload - True if equal - The other CoordinateSystem - - - Gets or creates a Geography coordinate system with the ID, or the default if null is given. - The coordinate system - The coordinate system id, according to the EPSG. Null indicates the default should be returned - - - Gets or creates a Geometry coordinate system with the ID, or the default if null is given. - The coordinate system - The coordinate system id, according to the EPSG. Null indicates the default should be returned - - - Returns a hash code for this instance. - A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - - - The coordinate system Id, no matter what scheme is used. - - - The Name of the Reference - - - Display the coordinate system for debugging - String representation of the coordinate system, for debugging - - - To a string that can be used with extended WKT. - String representation in the form of SRID=#; - - - Represents the extensions to formatters. - - - Writes the specified formatter. - A string value of the formatted object. - The formatter. - The spatial object. - - - Writes the specified formatter. - A string value of the formatted object. - The formatter. - The spatial object. - - - Represents a base class of geography shapes. - - - Initializes a new instance of the class. - The coordinate system of this geography. - The implementation that created this instance. - - - Gets the coordinate system of the geography. - The coordinate system of the geography. - - - Gets a value that indicates whether the geography is empty. - true if the geography is empty; otherwise, false. - - - Sends the current spatial object to the given pipeline. - The spatial pipeline. - - - Represents the collection of geographies. - - - Initializes a new instance of the class. - The coordinate system of this geography collection. - The implementation that created this instance. - - - Determines whether this instance and the specified object have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The object to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Gets the collection of geographies. - The collection of geographies. - - - Gets the hash code. - The hash code. - - - Represents the curve of geography. - - - Initializes a new instance of the class. - The coordinate system of this geography curve. - The implementation that created this instance. - - - Represents the full globe of geography. - - - Initializes a new instance of the class. - The coordinate system of this instance. - The implementation that created this instance. - - - Determines whether this instance and the specified object have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The object to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Gets the hash code. - The hash code. - - - Represents a geography line string consist of an array of geo points. - - - Initializes a new instance of the class. - The coordinate system of this instance. - The implementation that created this instance. - - - Determines whether this instance and the specified object have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The object to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Gets the hash code. - The hash code. - - - Gets the point list. - The point list. - - - Represents the multi curve of geography. - - - Initializes a new instance of the class. - The coordinate system of this instance. - The implementation that created this instance. - - - Geography Multi-LineString - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Line Strings - - - Geography Multi-Point - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Points - - - Geography Multi-Polygon - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Polygons - - - Geography MultiSurface - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Extension methods for the Geography operations - - - Geography Distance - The operation result - Operand 1 - Operand 2 - - - This is definition of the GeographyPipeline api - - - Initializes a new instance of the class. - - - Begin drawing a figure - Next position - - - Begin drawing a spatial object - The spatial type of the object - - - Ends the current figure - - - Ends the current spatial object - - - Draw a point in the specified coordinate - Next position - - - Setup the pipeline for reuse - - - Set the coordinate system - The CoordinateSystem - - - Geography point - - - Create a empty point - CoordinateSystem - The implementation that created this instance. - - - Creates the specified latitude. - The GeographyPoint that was created - The latitude. - The longitude. - - - Creates the specified latitude. - The GeographyPoint that was created - The latitude. - The longitude. - The z dimension. - - - Creates the specified latitude. - The GeographyPoint that was created - The latitude. - The longitude. - The z dimension. - The m dimension. - - - Creates the specified latitude. - The GeographyPoint that was created - the coordinate system to use - The latitude. - The longitude. - The z dimension. - The m dimension. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Latitude - - - Longitude - - - Nullable M - - - Nullable Z - - - Geography polygon - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Set of rings - - - Represents one position in the Geographyal coordinate system - - - Creates a GeographyPosition from components - lattitude portion of position - longitude portion of position - - - Creates a GeographyPosition from components - lattitude portion of position - longitude portion of position - altitude portion of position - arbitrary measure associated with a position - - - Equality comparison - true if each pair of coordinates is equal - other position - - - Equality comparison - true if each pair of coordinates is equal - other position - - - Computes a hash code - a hash code - - - lattitude portion of position - - - longitude portion of position - - - arbitrary measure associated with a position - - - Equality comparison - true if each pair of coordinates is equal - first position - second position - - - Inequality comparison - true if left is not equal to right - first position - other position - - - Formats this instance to a readable string - The string representation of this instance - - - altitude portion of position - - - Geography Surface - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Formatter for Json Object - - - Initializes a new instance of the class. - - - Creates the implementation of the formatter - Returns the created GeoJsonFormatter implementation - - - Read from the source - The source json object - The spatial type to read - - - Convert spatial value to a Json Object - The json object - The spatial value - - - Base class of Geography Shapes - - - Geometry Constructor - The CoordinateSystem - The implementation that created this instance. - - - SRID of this instance of geometry - - - Is Geometry Empty - - - Sends the current spatial object to the given pipeline - The spatial pipeline - - - Geometry Collection - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Returns the Geometry instances in this collection. - - - Get Hashcode - The hashcode - - - Geometry Curve - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Geometry Line String - - - Constructor - CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Point list - - - Geometry MultiCurve - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Geometry Multi-LineString - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Line Strings - - - Geometry Multi-Point - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Points - - - Geometry Multi-Polygon - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Polygons - - - - Extension methods for the Geography operations - - - Geometry Distance - The operation result - Operand 1 - Operand 2 - - - This is definition of the GeometryPipeline api - - - Initializes a new instance of the class. - - - Begin drawing a figure - Next position - - - Begin drawing a spatial object - The spatial type of the object - - - Ends the current figure - - - Ends the current spatial object - - - Draw a point in the specified coordinate - Next position - - - Setup the pipeline for reuse - - - Set the coordinate system - The CoordinateSystem - - - Geometry Point - - - Empty Point constructor - CoordinateSystem - The implementation that created this instance. - - - Creates the specified latitude. - The GeographyPoint that was created - The x dimension. - The y dimension. - - - Creates the specified latitude. - The GeographyPoint that was created - The x dimension. - The y dimension. - The z dimension. - - - Creates the specified latitude. - The GeographyPoint that was created - The x dimension. - The y dimension. - The z dimension. - The m dimension. - - - Creates the specified latitude. - The GeographyPoint that was created - the coordinate system to use - The x dimension. - The y dimension. - The z dimension. - The m dimension. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Nullable M - - - Latitude - - - Longitude - - - Nullable Z - - - Geometry polygon - - - Constructor - The CoordinateSystem - The implementation that created this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Determines whether this instance and another specified geography instance have the same value. - true if the value of the value parameter is the same as this instance; otherwise, false. - The geography to compare to this instance. - - - Get Hashcode - The hashcode - - - Set of rings - - - Represents one position in the Geometry coordinate system - - - Creates a GeometryPosition from components - x portion of position - y portion of position - - - Creates a GeometryPosition from components - x portion of position - y portion of position - altitude portion of position - arbitrary measure associated with a position - - - Equality comparison - true if each pair of coordinates is equal - other position - - - Equality comparison - true if each pair of coordinates is equal - other position - - - Computes a hash code - a hash code - - - arbitrary measure associated with a position - - - Equality comparison - true if each pair of coordinates is equal - first position - second position - - - Inequality comparison - true if left is not equal to right - first position - other position - - - Formats this instance to a readable string - The string representation of this instance - - - x portion of position - - - y portion of position - - - altitude portion of position - - - - The object to move spatial types to and from the GML format - - - Initializes a new instance of the class. - The implementation that created this instance. - - - Creates the implementation of the formatter - Returns the created GmlFormatter implementation - - - Provides access to the geography objects that this object constructs - - - Gets the geography object that was constructed most recently. - - - Fires when the provider constructs a geography object. - - - Provides access to the geometry objects that this object constructs - - - Gets the geometry object that was constructed most recently. - - - Fires when the provider constructs a geometry object. - - - - The spatial interface - - - Coordinate System - - - Is spatial type empty - - - the exception thrown on an unsuccessful parsing of the serialized format. - - - Creates a ParseErrorException - - - Creates a ParseErrorException from serialized data. - The instance that hosld the serialized object data about the exception being thrown. - The instance that contains contextual information about the source or destination. - - - Creates a ParseErrorException from a message - The message about the exception. - - - Creates a ParseErrorException from a message and previous exception - The message about the exception. - The exception that preceeded this one. - - - Creates Geometry or Geography instances from spatial data pipelines. - - - Initializes a new instance of the class. - The geography input. - The geometry input. - The geography output. - The geometry output. - - - Gets the geography object that was constructed most recently. - - - Gets the geometry object that was constructed most recently. - - - Creates an implementation of the builder - Returns the created SpatialBuilder implementation - - - Fires when the provider constructs a geography object. - - - Fires when the provider constructs a geometry object. - - - Base class for all Spatial Formats - The type of reader to be read from. - The type of reader to be read from. - - - Initializes a new instance of the <see cref="T:System.Spatial.SpatialFormatter`2" /> class. - The implementation that created this instance. - - - Creates the writerStream. - The writerStream that was created. - The stream that should be written to. - - - Creates the builder that will be called by the parser to build the new type. - the builder that was created. - - - Parses the input, and produces the object - The input to be parsed. - The type of object to produce - - - Parses the input, and produces the object - The input to be parsed. - The pipeline to call during reading. - The type of object to produce - - - Read the Geography from the readerStream and call the appopriate pipeline methods - The stream to read from. - The pipeline to call based on what is read. - - - Read the Geometry from the readerStream and call the appopriate pipeline methods - The stream to read from. - The pipeline to call based on what is read. - - - Creates a valid format from the spatial object. - The object that the format is being created for. - The stream to write the formatted object to. - - - Class responsible for knowing how to create the Geography and Geometry builders for a particular implemenation of Spatial types - - - Initializes a new instance of the class. - - - Creates a SpatialBuilder for this implemenation - The SpatialBuilder created. - - - Creates a Formatter for Json Object - The JsonObjectFormatter created - - - Creates a GmlFormatter for this implementation - The GmlFormatter created. - - - Creates a spatial Validator - The SpatialValidator created. - - - Creates a WellKnownTextSqlFormatter for this implementation - The WellKnownTextSqlFormatter created. - - - Creates a WellKnownTextSqlFormatter for this implementation - The WellKnownTextSqlFormatter created. - Controls the writing and reading of the Z and M dimension - - - Returns an instance of SpatialImplementation that is currently being used. - - - Property used to register Spatial operations implementation. - - - Class responsible for knowing how to perform operations for a particular implemenation of Spatial types - - - Initializes a new instance of the class. - - - Geography Distance - The operation result - Operand 1 - Operand 2 - - - Geometry Distance - The operation result - Operand 1 - Operand 2 - - - One link of a geospatial pipeline - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - The geography chain. - The geometry chain. - - - Add the next pipeline - The last pipesegment in the chain, usually the one just created - the next pipleine - - - Gets the geography side of the pipeline. - - - Gets the geometry side of the pipeline. - - - - - Gets or sets the starting link. - The starting link. - - - Defines a list of allowed OpenGisTypes types. - - - Unknown - - - Point - - - Line String - - - Polygon - - - Multi-Point - - - Multi-Line-String - - - Multi-Polygon - - - Collection - - - Full Globe - - - This class provides a place to add extension methods that work with ISpatial - - - Allows the delegation of the call to the proper type (geography or Geometry) - The instance that will have SendTo called. - The pipeline that the instance will be sent to. - - - Base class for Spatial Type Validator implementations - - - Factory for creating the currently registered SpatialValidator implementation - The created SpatialValidator - - - The object to move spatial types to and from the WellKnownTextSql format - - - Initializes a new instance of the class. - The implementation that created this instance. - - - Creates the implementation of the formatter - Returns the created WellKnownTextSqlFormatter implementation - - - Creates the specified has Z. - The created WellKnownTextSqlFormatter. - Restricts the formatter to allow only two dimensions. - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/ICancellableAsyncResult.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/ICancellableAsyncResult.cs deleted file mode 100644 index ed1ec3c6f7805..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/ICancellableAsyncResult.cs +++ /dev/null @@ -1,32 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - - /// - /// Represents the status of an asynchronous operation and provides support for cancellation. - /// - public interface ICancellableAsyncResult : IAsyncResult - { - /// - /// Cancels the asynchronous operation. - /// - void Cancel(); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueue.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueue.cs deleted file mode 100644 index 11530e1febd5c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueue.cs +++ /dev/null @@ -1,2750 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// This class represents a queue in the Windows Azure Queue service. - /// - public sealed partial class CloudQueue - { -#if SYNC - /// - /// Creates the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - [DoesServiceRequest] - public void Create(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.CreateQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to create a queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(AsyncCallback callback, object state) - { - return this.BeginCreate(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.CreateQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to create a queue. - /// - /// An that references the pending asynchronous operation. - public void EndCreate(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync() - { - return this.CreateAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.CreateAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Creates the queue if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// true if the queue did not already exist and was created; otherwise false. - [DoesServiceRequest] - public bool CreateIfNotExists(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - if (exists) - { - return false; - } - - try - { - this.Create(modifiedOptions, operationContext); - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NoContent) - { - return false; - } - - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == QueueErrorCodeStrings.QueueAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } -#endif - - /// - /// Begins an asynchronous request to create the queue if it does not already exist. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(AsyncCallback callback, object state) - { - return this.BeginCreateIfNotExists(null /* options */, null /*operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to create the queue if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult currentRes = this.BeginExists(modifiedOptions, operationContext, this.CreateIfNotExistsHandler, storageAsyncResult); - storageAsyncResult.CancelDelegate = currentRes.Cancel; - - // Check if cancellation was requested prior to begin - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.CancelDelegate(); - } - } - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void CreateIfNotExistsHandler(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = asyncResult.AsyncState as StorageAsyncResult; - bool exists = false; - - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously); - - try - { - exists = this.EndExists(asyncResult); - - if (exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - ICancellableAsyncResult currentRes = this.BeginCreate( - (QueueRequestOptions)storageAsyncResult.RequestOptions, - storageAsyncResult.OperationContext, - createRes => - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(createRes.CompletedSynchronously); - - try - { - this.EndCreate(createRes); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == QueueErrorCodeStrings.QueueAlreadyExists)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception createEx) - { - storageAsyncResult.OnComplete(createEx); - } - }, - null); - - storageAsyncResult.CancelDelegate = currentRes.Cancel; - } - } - catch (Exception ex) - { - storageAsyncResult.OnComplete(ex); - } - } - } - - /// - /// Returns the result of an asynchronous request to create the queue if it does not already exist. - /// - /// An that references the pending asynchronous operation. - /// true if the queue did not already exist and was created; otherwise, false. - public bool EndCreateIfNotExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to create the queue if it does not already exist. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to create the queue if it does not already exist. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to create the queue if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.CreateIfNotExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to create the queue if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the queue if it already exists. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// true if the queue did not already exist and was created; otherwise false. - [DoesServiceRequest] - public bool DeleteIfExists(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - bool exists = this.Exists(modifiedOptions, operationContext); - if (!exists) - { - return false; - } - - try - { - this.Delete(modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == QueueErrorCodeStrings.QueueNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } - -#endif - /// - /// Begins an asynchronous request to delete the queue if it already exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state) - { - return this.BeginDeleteIfExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to delete the queue if it already exists. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult storageAsyncResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext, - }; - - lock (storageAsyncResult.CancellationLockerObject) - { - ICancellableAsyncResult currentRes = this.BeginExists(modifiedOptions, operationContext, this.DeleteIfExistsHandler, storageAsyncResult); - storageAsyncResult.CancelDelegate = currentRes.Cancel; - - // Check if cancellation was requested prior to begin - if (storageAsyncResult.CancelRequested) - { - storageAsyncResult.CancelDelegate(); - } - } - - return storageAsyncResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void DeleteIfExistsHandler(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = asyncResult.AsyncState as StorageAsyncResult; - bool exists = false; - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously); - - try - { - exists = this.EndExists(asyncResult); - - if (!exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - ICancellableAsyncResult currentRes = this.BeginDelete( - (QueueRequestOptions)storageAsyncResult.RequestOptions, - storageAsyncResult.OperationContext, - (deleteRes) => - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(deleteRes.CompletedSynchronously); - - try - { - this.EndDelete(deleteRes); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == QueueErrorCodeStrings.QueueNotFound)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception createEx) - { - storageAsyncResult.OnComplete(createEx); - } - }, - null); - - storageAsyncResult.CancelDelegate = currentRes.Cancel; - } - } - catch (Exception ex) - { - storageAsyncResult.OnComplete(ex); - } - } - } - - /// - /// Returns the result of an asynchronous request to delete the queue if it already exists. - /// - /// An that references the pending asynchronous operation. - /// true if the queue did not already exist and was created; otherwise, false. - public bool EndDeleteIfExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to delete the queue if it already exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the queue if it already exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to delete the queue if it already exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.DeleteIfExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to delete the queue if it already exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - [DoesServiceRequest] - public void Delete(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.DeleteQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to delete a queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state) - { - return this.BeginDelete(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.DeleteQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to delete a queue. - /// - /// An that references the pending asynchronous operation. - public void EndDelete(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete a queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync() - { - return this.DeleteAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.DeleteAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that specifies additional options for the request. - /// An 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. - [DoesServiceRequest] - public void SetPermissions(QueuePermissions permissions, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.SetPermissionsImpl(permissions, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(QueuePermissions permissions, AsyncCallback callback, object state) - { - return this.BeginSetPermissions(permissions, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(QueuePermissions permissions, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.SetPermissionsImpl(permissions, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the result of an asynchronous request to set permissions for the queue. - /// - /// An that references the pending asynchronous operation. - public void EndSetPermissions(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(QueuePermissions permissions) - { - return this.SetPermissionsAsync(permissions, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(QueuePermissions permissions, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(QueuePermissions permissions, QueueRequestOptions options, OperationContext operationContext) - { - return this.SetPermissionsAsync(permissions, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(QueuePermissions permissions, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets the permissions settings for the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The queue's permissions. - [DoesServiceRequest] - public QueuePermissions GetPermissions(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.ExecuteSync( - this.GetPermissionsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to get the permissions settings for the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(AsyncCallback callback, object state) - { - return this.BeginGetPermissions(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to get the permissions settings for the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.GetPermissionsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to get the permissions settings for the queue. - /// - /// An that references the pending asynchronous operation. - /// The queue's permissions. - public QueuePermissions EndGetPermissions(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync() - { - return this.GetPermissionsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.GetPermissionsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Checks existence of the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// true if the queue exists. - [DoesServiceRequest] - public bool Exists(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.ExecuteSync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous request to check existence of the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(AsyncCallback callback, object state) - { - return this.BeginExists(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to check existence of the queue. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to check existence of the queue. - /// - /// An that references the pending asynchronous operation. - /// true if the queue exists. - public bool EndExists(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to check existence of the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync() - { - return this.ExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.ExistsAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to check existence of the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the queue's user-defined metadata. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - [DoesServiceRequest] - public void SetMetadata(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.SetMetadataImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set user-defined metadata on the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(AsyncCallback callback, object state) - { - return this.BeginSetMetadata(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set user-defined metadata on the queue. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetMetadata(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.SetMetadataImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous request operation to set user-defined metadata on the queue. - /// - /// An that references the pending asynchronous operation. - public void EndSetMetadata(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to set user-defined metadata on the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync() - { - return this.SetMetadataAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set user-defined metadata on the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to set user-defined metadata on the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.SetMetadataAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set user-defined metadata on the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetMetadataAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetMetadata, this.EndSetMetadata, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Fetches the queue's attributes. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - [DoesServiceRequest] - public void FetchAttributes(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.FetchAttributesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to fetch the queue's attributes. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(AsyncCallback callback, object state) - { - return this.BeginFetchAttributes(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to fetch the queue's attributes. - /// - /// A object that specifies additional options for the request. - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginFetchAttributes(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.FetchAttributesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to fetch a queue's attributes. - /// - /// An that references the pending asynchronous operation. - public void EndFetchAttributes(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to fetch the queue's attributes. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync() - { - return this.FetchAttributesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to fetch the queue's attributes. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to fetch the queue's attributes. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.FetchAttributesAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to fetch the queue's attributes. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task FetchAttributesAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginFetchAttributes, this.EndFetchAttributes, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Adds a message to the queue. - /// - /// The message to add. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void AddMessage(CloudQueueMessage message, TimeSpan? timeToLive = null, TimeSpan? initialVisibilityDelay = null, QueueRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("message", message); - - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.AddMessageImpl(message, timeToLive, initialVisibilityDelay, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAddMessage(CloudQueueMessage message, AsyncCallback callback, object state) - { - return this.BeginAddMessage(message, null /* timeToLive */, null /* initialVisibilityDelay */, null /* options */, null /*operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginAddMessage(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("message", message); - - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.AddMessageImpl(message, timeToLive, initialVisibilityDelay, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to add a message to the queue. - /// - /// An that references the pending asynchronous operation. - public void EndAddMessage(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AddMessageAsync(CloudQueueMessage message) - { - return this.AddMessageAsync(message, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AddMessageAsync(CloudQueueMessage message, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAddMessage, this.EndAddMessage, message, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AddMessageAsync(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options, OperationContext operationContext) - { - return this.AddMessageAsync(message, timeToLive, initialVisibilityDelay, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to add a message to the queue. - /// - /// The message to add. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task AddMessageAsync(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginAddMessage, this.EndAddMessage, message, timeToLive, initialVisibilityDelay, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Updates the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// Flags of values that specifies which parts of the message are to be updated. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - [DoesServiceRequest] - public void UpdateMessage(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.UpdateMessageImpl(message, visibilityTimeout, updateFields, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUpdateMessage(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, AsyncCallback callback, object state) - { - return this.BeginUpdateMessage(message, visibilityTimeout, updateFields, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginUpdateMessage(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("message", message); - - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.UpdateMessageImpl(message, visibilityTimeout, updateFields, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to add a message to the queue. - /// - /// An that references the pending asynchronous operation. - public void EndUpdateMessage(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields) - { - return this.UpdateMessageAsync(message, visibilityTimeout, updateFields, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUpdateMessage, this.EndUpdateMessage, message, visibilityTimeout, updateFields, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options, OperationContext operationContext) - { - return this.UpdateMessageAsync(message, visibilityTimeout, updateFields, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to update the visibility timeout and optionally the content of a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// An EnumSet of values that specifies which parts of the message are to be updated. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginUpdateMessage, this.EndUpdateMessage, message, visibilityTimeout, updateFields, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Deletes a message. - /// - /// A message. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - [DoesServiceRequest] - public void DeleteMessage(CloudQueueMessage message, QueueRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("message", message); - - this.DeleteMessage(message.Id, message.PopReceipt, options, operationContext); - } - - /// - /// Deletes the specified message from the queue. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - [DoesServiceRequest] - public void DeleteMessage(string messageId, string popReceipt, QueueRequestOptions options = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("messageId", messageId); - CommonUtility.AssertNotNull("popReceipt", popReceipt); - - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.DeleteMessageImpl(messageId, popReceipt, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to delete a message. - /// - /// A message. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteMessage(CloudQueueMessage message, AsyncCallback callback, object state) - { - return this.BeginDeleteMessage(message, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a message. - /// - /// A message. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteMessage(CloudQueueMessage message, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("message", message); - - return this.BeginDeleteMessage(message.Id, message.PopReceipt, options, operationContext, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteMessage(string messageId, string popReceipt, AsyncCallback callback, object state) - { - return this.BeginDeleteMessage(messageId, popReceipt, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteMessage(string messageId, string popReceipt, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("messageId", messageId); - CommonUtility.AssertNotNull("popReceipt", popReceipt); - - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.DeleteMessageImpl(messageId, popReceipt, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to delete a message. - /// - /// An that references the pending asynchronous operation. - public void EndDeleteMessage(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// A message. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(CloudQueueMessage message) - { - return this.DeleteMessageAsync(message, null /* options */, null /* operationContext */, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// A message. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(CloudQueueMessage message, CancellationToken cancellationToken) - { - return this.DeleteMessageAsync(message, null /* options */, null /* operationContext */, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// A message. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(CloudQueueMessage message, QueueRequestOptions options, OperationContext operationContext) - { - return this.DeleteMessageAsync(message, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// A message. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(CloudQueueMessage message, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDeleteMessage, this.EndDeleteMessage, message, options, operationContext, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(string messageId, string popReceipt) - { - return this.DeleteMessageAsync(messageId, popReceipt, null /* options */, null /* operationContext */, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(string messageId, string popReceipt, CancellationToken cancellationToken) - { - return this.DeleteMessageAsync(messageId, popReceipt, null /* options */, null /* operationContext */, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(string messageId, string popReceipt, QueueRequestOptions options, OperationContext operationContext) - { - return this.DeleteMessageAsync(messageId, popReceipt, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a message. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteMessageAsync(string messageId, string popReceipt, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDeleteMessage, this.EndDeleteMessage, messageId, popReceipt, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets the specified number of messages from the queue using the specified request options and - /// operation context. This operation marks the retrieved messages as invisible in the queue for the default - /// visibility timeout period. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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 enumerable collection of messages. - [DoesServiceRequest] - public IEnumerable GetMessages(int messageCount, TimeSpan? visibilityTimeout = null, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.ExecuteSync( - this.GetMessagesImpl(messageCount, visibilityTimeout, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to get messages from the queue. - /// - /// The number of messages to retrieve. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetMessages(int messageCount, AsyncCallback callback, object state) - { - return this.BeginGetMessages(messageCount, null /* visibilityTimeout */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get the specified number of messages from the queue using the - /// specified request options and operation context. This operation marks the retrieved messages as invisible in the - /// queue for the default visibility timeout period. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetMessages(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.GetMessagesImpl(messageCount, visibilityTimeout, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to get messages from the queue. - /// - /// An that references the pending asynchronous operation. - /// An enumerable collection of messages. - public IEnumerable EndGetMessages(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get messages from the queue. - /// - /// The number of messages to retrieve. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetMessagesAsync(int messageCount) - { - return this.GetMessagesAsync(messageCount, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get messages from the queue. - /// - /// The number of messages to retrieve. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetMessagesAsync(int messageCount, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetMessages, this.EndGetMessages, messageCount, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get the specified number of messages from the queue using the - /// specified request options and operation context. This operation marks the retrieved messages as invisible in the - /// queue for the default visibility timeout period. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetMessagesAsync(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext) - { - return this.GetMessagesAsync(messageCount, visibilityTimeout, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the specified number of messages from the queue using the - /// specified request options and operation context. This operation marks the retrieved messages as invisible in the - /// queue for the default visibility timeout period. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> GetMessagesAsync(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetMessages, this.EndGetMessages, messageCount, visibilityTimeout, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets a message from the queue using the default request options. This operation marks the retrieved message as invisible in the queue for the default visibility timeout period. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// A message. - [DoesServiceRequest] - public CloudQueueMessage GetMessage(TimeSpan? visibilityTimeout = null, QueueRequestOptions options = null, OperationContext operationContext = null) - { - return this.GetMessages(1, visibilityTimeout, options, operationContext).FirstOrDefault(); - } -#endif - - /// - /// Begins an asynchronous operation to get a single message from the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetMessage(AsyncCallback callback, object state) - { - return this.BeginGetMessage(null /* visibilityTimeout */, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get a single message from the queue, and specifies how long the message should be - /// reserved before it becomes visible, and therefore available for deletion. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetMessage(TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginGetMessages(1, visibilityTimeout, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to get a single message from the queue. - /// - /// An that references the pending asynchronous operation. - /// A message. - public CloudQueueMessage EndGetMessage(IAsyncResult asyncResult) - { - IEnumerable resultList = Executor.EndExecuteAsync>(asyncResult); - - return resultList.FirstOrDefault(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetMessageAsync() - { - return this.GetMessageAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetMessageAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetMessage, this.EndGetMessage, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue, and specifies how long the message should be - /// reserved before it becomes visible, and therefore available for deletion. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetMessageAsync(TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext) - { - return this.GetMessageAsync(visibilityTimeout, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue, and specifies how long the message should be - /// reserved before it becomes visible, and therefore available for deletion. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetMessageAsync(TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetMessage, this.EndGetMessage, visibilityTimeout, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Peeks a message from the queue, using the specified request options and operation context. A peek request retrieves a message from the queue without changing its visibility. - /// - /// The number of messages to peek. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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 enumerable collection of messages. - [DoesServiceRequest] - public IEnumerable PeekMessages(int messageCount, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.ExecuteSync( - this.PeekMessagesImpl(messageCount, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPeekMessages(int messageCount, AsyncCallback callback, object state) - { - return this.BeginPeekMessages(messageCount, null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPeekMessages(int messageCount, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.PeekMessagesImpl(messageCount, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to peek messages from the queue. - /// - /// An that references the pending asynchronous operation. - /// An enumerable collection of messages. - public IEnumerable EndPeekMessages(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> PeekMessagesAsync(int messageCount) - { - return this.PeekMessagesAsync(messageCount, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> PeekMessagesAsync(int messageCount, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginPeekMessages, this.EndPeekMessages, messageCount, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> PeekMessagesAsync(int messageCount, QueueRequestOptions options, OperationContext operationContext) - { - return this.PeekMessagesAsync(messageCount, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to peek messages from the queue. - /// - /// The number of messages to peek. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> PeekMessagesAsync(int messageCount, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginPeekMessages, this.EndPeekMessages, messageCount, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Peeks a single message from the queue. A peek request retrieves a message from the queue without changing its visibility. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// A message. - [DoesServiceRequest] - public CloudQueueMessage PeekMessage(QueueRequestOptions options = null, OperationContext operationContext = null) - { - return this.PeekMessages(1, options, operationContext).FirstOrDefault(); - } -#endif - - /// - /// Begins an asynchronous operation to get a single message from the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPeekMessage(AsyncCallback callback, object state) - { - return this.BeginPeekMessage(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to peek a single message from the queue. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginPeekMessage(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - return this.BeginPeekMessages(1, options, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to peek a single message from the queue. - /// - /// An that references the pending asynchronous operation. - /// A message. - public CloudQueueMessage EndPeekMessage(IAsyncResult asyncResult) - { - IEnumerable resultList = Executor.EndExecuteAsync>(asyncResult); - - return resultList.FirstOrDefault(); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PeekMessageAsync() - { - return this.PeekMessageAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PeekMessageAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginPeekMessage, this.EndPeekMessage, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PeekMessageAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.PeekMessageAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get a single message from the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task PeekMessageAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginPeekMessage, this.EndPeekMessage, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Clears all messages from the queue. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - [DoesServiceRequest] - public void Clear(QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - Executor.ExecuteSync( - this.ClearMessagesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to clear all messages from the queue. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginClear(AsyncCallback callback, object state) - { - return this.BeginClear(null /* options */, null /* operationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to clear all messages from the queue. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An 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. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginClear(QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.ClearMessagesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to clear all messages from the queue. - /// - /// An that references the pending asynchronous operation. - public void EndClear(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to clear all messages from the queue. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearAsync() - { - return this.ClearAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to clear all messages from the queue. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginClear, this.EndClear, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to clear all messages from the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearAsync(QueueRequestOptions options, OperationContext operationContext) - { - return this.ClearAsync(options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to clear all messages from the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ClearAsync(QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginClear, this.EndClear, options, operationContext, cancellationToken); - } -#endif - - /// - /// Ends an asynchronous operation to clear all messages from the queue. - /// - /// An that references the pending asynchronous operation. - [Obsolete("This class is improperly named; use class EndClear instead.")] - [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Reviewed.")] - public void EndBeginClear(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - - /// - /// Implementation for the ClearMessages method. - /// - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand ClearMessagesImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.ClearMessages(uri, serverTimeout, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the Create method. - /// - /// A object that specifies additional options for the request. - /// A that creates the queue. - private RESTCommand CreateQueueImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.Create(uri, serverTimeout, ctx); - putCmd.SetHeaders = (r, ctx) => QueueHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpStatusCode[] expectedHttpStatusCodes = new HttpStatusCode[2]; - expectedHttpStatusCodes[0] = HttpStatusCode.Created; - expectedHttpStatusCodes[1] = HttpStatusCode.NoContent; - HttpResponseParsers.ProcessExpectedStatusCodeNoException(expectedHttpStatusCodes, resp, NullType.Value, cmd, ex); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Delete method. - /// - /// A object that specifies additional options for the request. - /// A that deletes the queue. - private RESTCommand DeleteQueueImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.Delete(uri, serverTimeout, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the FetchAttributes method. - /// - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand FetchAttributesImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.GetMetadata(uri, serverTimeout, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implementation for the Exists method. - /// - /// A object that specifies additional options for the request. - /// A that checks existence. - private RESTCommand ExistsImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.GetMetadata(uri, serverTimeout, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - if (resp.StatusCode == HttpStatusCode.PreconditionFailed) - { - return true; - } - - return HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand SetMetadataImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.SetMetadata(uri, serverTimeout, ctx); - putCmd.SetHeaders = (r, ctx) => QueueHttpWebRequestFactory.AddMetadata(r, this.Metadata); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetPermissions method. - /// - /// The permissions to set. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand SetPermissionsImpl(QueuePermissions acl, QueueRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - QueueRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.SetAcl(uri, serverTimeout, ctx); - putCmd.SendStream = memoryStream; - putCmd.RecoveryAction = RecoveryActions.RewindStream; - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetPermissionsImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.GetAcl(uri, serverTimeout, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - QueuePermissions queueAcl = new QueuePermissions(); - QueueHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, queueAcl); - return queueAcl; - }; - - return getCmd; - } - - /// - /// Implementation for the AddMessageImpl method. - /// - /// A queue message. - /// A value indicating the message time-to-live. - /// The visibility delay for the message. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand AddMessageImpl(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options) - { - int? timeToLiveInSeconds = null; - int? initialVisibilityDelayInSeconds = null; - - if (timeToLive != null) - { - CommonUtility.AssertInBounds("timeToLive", timeToLive.Value, TimeSpan.Zero, CloudQueueMessage.MaxTimeToLive); - timeToLiveInSeconds = (int)timeToLive.Value.TotalSeconds; - } - - if (initialVisibilityDelay != null) - { - CommonUtility.AssertInBounds("initialVisibilityDelay", initialVisibilityDelay.Value, TimeSpan.Zero, timeToLive ?? CloudQueueMessage.MaxTimeToLive); - initialVisibilityDelayInSeconds = (int)initialVisibilityDelay.Value.TotalSeconds; - } - - CommonUtility.AssertNotNull("message", message); - - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - QueueRequest.WriteMessageContent(message.GetMessageContentForTransfer(this.EncodeMessage), memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.AddMessage(putCmd.Uri, serverTimeout, timeToLiveInSeconds, initialVisibilityDelayInSeconds, ctx); - putCmd.SendStream = memoryStream; - putCmd.RecoveryAction = RecoveryActions.RewindStream; - putCmd.SetHeaders = (r, ctx) => - { - if (timeToLive != null) - { -#if WINDOWS_PHONE - r.Headers[Constants.QueryConstants.MessageTimeToLive] = timeToLive.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture); -#else - r.Headers.Set(Constants.QueryConstants.MessageTimeToLive, timeToLive.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture)); -#endif - } - - if (initialVisibilityDelay != null) - { -#if WINDOWS_PHONE - r.Headers[Constants.QueryConstants.VisibilityTimeout] = initialVisibilityDelay.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture); -#else - r.Headers.Set(Constants.QueryConstants.VisibilityTimeout, initialVisibilityDelay.Value.TotalSeconds.ToString(CultureInfo.InvariantCulture)); -#endif - } - }; - - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the UpdateMessage method. - /// - /// A queue message. - /// The visibility timeout for the message. - /// Indicates whether to update the visibility delay, message contents, or both. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand UpdateMessageImpl(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options) - { - CommonUtility.AssertNotNull("message", message); - CommonUtility.AssertNotNullOrEmpty("messageId", message.Id); - CommonUtility.AssertNotNullOrEmpty("popReceipt", message.PopReceipt); - CommonUtility.AssertInBounds("visibilityTimeout", visibilityTimeout, TimeSpan.Zero, CloudQueueMessage.MaxTimeToLive); - - if ((updateFields & MessageUpdateFields.Visibility) == 0) - { - throw new ArgumentException(SR.UpdateMessageVisibilityRequired, "updateFields"); - } - - Uri messageUri = this.GetIndividualMessageAddress(message.Id); - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, messageUri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.UpdateMessage(putCmd.Uri, serverTimeout, message.PopReceipt, visibilityTimeout.RoundUpToSeconds(), ctx); - - if ((updateFields & MessageUpdateFields.Content) != 0) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager, (int)(1 * Constants.KB)); - QueueRequest.WriteMessageContent(message.GetMessageContentForTransfer(this.EncodeMessage), memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - putCmd.SendStream = memoryStream; - putCmd.RecoveryAction = RecoveryActions.RewindStream; - } - - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - GetPopReceiptAndNextVisibleTimeFromResponse(message, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the DeleteMessage method. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. - /// A that deletes the queue. - private RESTCommand DeleteMessageImpl(string messageId, string popReceipt, QueueRequestOptions options) - { - Uri messageUri = this.GetIndividualMessageAddress(messageId); - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, messageUri); - - putCmd.ApplyRequestOptions(options); - putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.DeleteMessage(putCmd.Uri, serverTimeout, popReceipt, ctx); - putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand> GetMessagesImpl(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.GetMessages(getCmd.Uri, serverTimeout, messageCount, visibilityTimeout, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - GetMessagesResponse getMessagesResponse = new GetMessagesResponse(cmd.ResponseStream); - - List messagesList = new List( - getMessagesResponse.Messages.Select(item => SelectGetMessageResponse(item))); - - return messagesList; - }; - - return getCmd; - } - - /// - /// Implementation for the PeekMessages method. - /// - /// The number of messages to retrieve. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand> PeekMessagesImpl(int messageCount, QueueRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.PeekMessages(getCmd.Uri, serverTimeout, messageCount, ctx); - getCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - GetMessagesResponse getMessagesResponse = new GetMessagesResponse(cmd.ResponseStream); - - List messagesList = new List( - getMessagesResponse.Messages.Select(item => SelectPeekMessageResponse(item))); - - return messagesList; - }; - - return getCmd; - } - - /// - /// Gets the ApproximateMessageCount and metadata from response. - /// - /// The web response. - private void GetMessageCountAndMetadataFromResponse(HttpWebResponse webResponse) - { - this.Metadata = QueueHttpResponseParsers.GetMetadata(webResponse); - - string count = QueueHttpResponseParsers.GetApproximateMessageCount(webResponse); - this.ApproximateMessageCount = string.IsNullOrEmpty(count) ? (int?)null : int.Parse(count, CultureInfo.InvariantCulture); - } - - /// - /// Update the message pop receipt and next visible time. - /// - /// The Cloud Queue Message. - /// The web response. - private static void GetPopReceiptAndNextVisibleTimeFromResponse(CloudQueueMessage message, HttpWebResponse webResponse) - { - message.PopReceipt = webResponse.Headers[Constants.HeaderConstants.PopReceipt]; - message.NextVisibleTime = DateTime.Parse( - webResponse.Headers[Constants.HeaderConstants.NextVisibleTime], - DateTimeFormatInfo.InvariantInfo, - DateTimeStyles.AdjustToUniversal); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueClient.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueClient.cs deleted file mode 100644 index 777e4841a87c1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueClient.cs +++ /dev/null @@ -1,636 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Provides a client-side logical representation of the Windows Azure Queue service. This client is used to configure and execute requests against the Queue service. - /// - /// The service client encapsulates the base URI for the Queue service. If the service client will be used for authenticated access, it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudQueueClient - { - private IAuthenticationHandler authenticationHandler; - - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - if (value != this.authenticationScheme) - { - this.authenticationScheme = value; - this.authenticationHandler = null; - } - } - } - - /// - /// Gets the authentication handler used to sign HTTP requests. - /// - /// The authentication handler. - internal IAuthenticationHandler AuthenticationHandler - { - get - { - IAuthenticationHandler result = this.authenticationHandler; - if (result == null) - { - if (this.Credentials.IsSharedKey) - { - result = new SharedKeyAuthenticationHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - result = new NoOpAuthenticationHandler(); - } - - this.authenticationHandler = result; - } - - return result; - } - } - -#if SYNC - /// - /// Returns an enumerable collection of the queues in the storage account whose names begin with the specified prefix and that are retrieved lazily. - /// - /// The queue name prefix. - /// An enumeration value that indicates which details to include in the listing. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// An enumerable collection of objects that implement and are retrieved lazily. - public IEnumerable ListQueues(string prefix = null, QueueListingDetails queueListingDetails = QueueListingDetails.None, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this); - operationContext = operationContext ?? new OperationContext(); - - return CommonUtility.LazyEnumerable( - (token) => this.ListQueuesSegmentedCore(prefix, queueListingDetails, null, token as QueueContinuationToken, modifiedOptions, operationContext), - long.MaxValue); - } - - /// - /// Returns a result segment containing a collection of queues in the storage account. - /// - /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement . - public QueueResultSegment ListQueuesSegmented(QueueContinuationToken currentToken) - { - return this.ListQueuesSegmented(null, QueueListingDetails.None, null, currentToken, null, null); - } - - /// - /// Returns a result segment containing a collection of queues in the storage account. - /// - /// The queue name prefix. - /// A continuation token returned by a previous listing operation. - /// A result segment containing objects that implement . - public QueueResultSegment ListQueuesSegmented(string prefix, QueueContinuationToken currentToken) - { - return this.ListQueuesSegmented(prefix, QueueListingDetails.None, null, currentToken, null, null); - } - - /// - /// Returns a result segment containing a collection of queues in the storage account. - /// - /// The queue name prefix. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// A result segment containing objects that implement . - public QueueResultSegment ListQueuesSegmented(string prefix, QueueListingDetails queueListingDetails, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options = null, OperationContext operationContext = null) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this); - operationContext = operationContext ?? new OperationContext(); - - ResultSegment resultSegment = this.ListQueuesSegmentedCore(prefix, queueListingDetails, maxResults, currentToken, modifiedOptions, operationContext); - return new QueueResultSegment(resultSegment.Results, (QueueContinuationToken)resultSegment.ContinuationToken); - } - - /// - /// Returns a result segment containing a collection of queues in the storage account. - /// - /// The queue name prefix. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// A result segment. - private ResultSegment ListQueuesSegmentedCore(string prefix, QueueListingDetails queueListingDetails, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options, OperationContext operationContext) - { - return Executor.ExecuteSync( - this.ListQueuesImpl(prefix, maxResults, queueListingDetails, options, currentToken), - options.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// A returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginListQueuesSegmented(QueueContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListQueuesSegmented(null, QueueListingDetails.None, null, currentToken, null, null, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginListQueuesSegmented(string prefix, QueueContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListQueuesSegmented(prefix, QueueListingDetails.None, null, currentToken, null, null, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - public ICancellableAsyncResult BeginListQueuesSegmented(string prefix, QueueListingDetails queueListingDetails, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options, OperationContext operationContext, AsyncCallback callback, object state) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this); - - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - this.ListQueuesImpl(prefix, maxResults, queueListingDetails, modifiedOptions, currentToken), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// An that references the pending asynchronous operation. - /// A queue result segment. - public QueueResultSegment EndListQueuesSegmented(IAsyncResult asyncResult) - { - ResultSegment resultSegment = Executor.EndExecuteAsync>(asyncResult); - return new QueueResultSegment(resultSegment.Results, (QueueContinuationToken)resultSegment.ContinuationToken); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// A returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(QueueContinuationToken currentToken) - { - return this.ListQueuesSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// A returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(QueueContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListQueuesSegmented, this.EndListQueuesSegmented, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(string prefix, QueueContinuationToken currentToken) - { - return this.ListQueuesSegmentedAsync(prefix, currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(string prefix, QueueContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListQueuesSegmented, this.EndListQueuesSegmented, prefix, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(string prefix, QueueListingDetails queueListingDetails, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options, OperationContext operationContext) - { - return this.ListQueuesSegmentedAsync(prefix, queueListingDetails, maxResults, currentToken, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection of queue items. - /// - /// The queue name prefix. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListQueuesSegmentedAsync(string prefix, QueueListingDetails queueListingDetails, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListQueuesSegmented, this.EndListQueuesSegmented, prefix, queueListingDetails, maxResults, currentToken, options, operationContext, cancellationToken); - } -#endif - - /// - /// Core implementation of the ListQueues method. - /// - /// The queue name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A enumeration describing which items to include in the listing. - /// An object that specifies additional options for the request. - /// The continuation token. - /// A that lists the queues. - private RESTCommand> ListQueuesImpl(string prefix, int? maxResults, QueueListingDetails queueListingDetails, QueueRequestOptions options, QueueContinuationToken currentToken) - { - QueueListingContext listingContext = new QueueListingContext(prefix, maxResults, queueListingDetails) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.Credentials, this.BaseUri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => QueueHttpWebRequestFactory.List(uri, serverTimeout, listingContext, queueListingDetails, ctx); - getCmd.SignRequest = this.AuthenticationHandler.SignRequest; - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ListQueuesResponse listQueuesResponse = new ListQueuesResponse(cmd.ResponseStream); - - List queuesList = new List( - listQueuesResponse.Queues.Select(item => new CloudQueue(item.Name, this))); - - QueueContinuationToken continuationToken = null; - if (listQueuesResponse.NextMarker != null) - { - continuationToken = new QueueContinuationToken() - { - NextMarker = listQueuesResponse.NextMarker, - }; - } - - return new ResultSegment(queuesList) - { - ContinuationToken = continuationToken, - }; - }; - - return getCmd; - } - - #region Analytics - - /// - /// Begins an asynchronous operation to get the properties of the queue service. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(AsyncCallback callback, object state) - { - return this.BeginGetServiceProperties(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get the properties of the queue service. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(QueueRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = QueueRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.GetServicePropertiesImpl(requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to get the properties of the queue service. - /// - /// The result returned from a prior call to . - /// A object containing the queue service properties. - public ServiceProperties EndGetServiceProperties(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get the properties of the queue service. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the queue service. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the queue service. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(QueueRequestOptions requestOptions, OperationContext operationContext) - { - return this.GetServicePropertiesAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the properties of the queue service. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(QueueRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, requestOptions, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Gets the properties of the queue service. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// The queue service properties. - [DoesServiceRequest] - public ServiceProperties GetServiceProperties(QueueRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = QueueRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.ExecuteSync( - this.GetServicePropertiesImpl(requestOptions), - requestOptions.RetryPolicy, - operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, AsyncCallback callback, object state) - { - return this.BeginSetServiceProperties(properties, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, QueueRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = QueueRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.SetServicePropertiesImpl(properties, requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to set the properties of the queue service. - /// - /// The result returned from a prior call to . - public void EndSetServiceProperties(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, QueueRequestOptions options, OperationContext operationContext) - { - return this.SetServicePropertiesAsync(properties, options, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the properties of the queue service. - /// - /// The queue service properties. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, QueueRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, options, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the properties of the queue service. - /// - /// The queue service properties. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - [DoesServiceRequest] - public void SetServiceProperties(ServiceProperties properties, QueueRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = QueueRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - Executor.ExecuteSync(this.SetServicePropertiesImpl(properties, requestOptions), requestOptions.RetryPolicy, operationContext); - } -#endif - - private RESTCommand GetServicePropertiesImpl(QueueRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequestDelegate = QueueHttpWebRequestFactory.GetServiceProperties; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.RetrieveResponseStream = true; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - retCmd.PostProcessResponse = - (cmd, resp, ctx) => QueueHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, QueueRequestOptions requestOptions) - { - MultiBufferMemoryStream str = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(str); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - str.Seek(0, SeekOrigin.Begin); - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.SendStream = str; - retCmd.BuildRequestDelegate = QueueHttpWebRequestFactory.SetServiceProperties; - retCmd.RecoveryAction = RecoveryActions.RewindStream; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueMessage.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueMessage.cs deleted file mode 100644 index 1efb3ff1aa752..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/CloudQueueMessage.cs +++ /dev/null @@ -1,49 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using System; - - /// - /// Represents a message in the Windows Azure Queue service. - /// - public sealed partial class CloudQueueMessage - { - /// - /// Initializes a new instance of the class with the given byte array. - /// - /// The content of the message as a byte array. - public CloudQueueMessage(byte[] content) - { - this.SetMessageContent(content); - - // While binary messages will be Base64-encoded and we could validate the message size here, - // for consistency, we leave it to CloudQueue so that we have a central place for this logic. - } - - /// - /// Sets the content of this message. - /// - /// The new message content. - public void SetMessageContent(byte[] content) - { - this.RawString = Convert.ToBase64String(content); - this.MessageType = QueueMessageType.Base64Encoded; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpResponseParsers.cs deleted file mode 100644 index 5fd020890754f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpResponseParsers.cs +++ /dev/null @@ -1,90 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Net; - - /// - /// Provides a set of methods for parsing a response containing queue data from the Queue service. - /// - public static partial class QueueHttpResponseParsers - { - /// - /// Gets the request ID from the response. - /// - /// The web response. - /// A unique value associated with the request. - public static string GetRequestId(HttpWebResponse response) - { - return Response.GetRequestId(response); - } - - /// - /// Gets the approximate message count for the queue. - /// - /// The web response. - /// The approximate count for the queue. - public static string GetApproximateMessageCount(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - return response.Headers[Constants.HeaderConstants.ApproximateMessagesCount]; - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// An object of type containing the metadata. - public static IDictionary GetMetadata(HttpWebResponse response) - { - return HttpResponseParsers.GetMetadata(response); - } - - /// - /// Extracts the pop receipt from a web response header. - /// - /// The web response. - /// The pop receipt stored in the header of the response. - public static string GetPopReceipt(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - return response.Headers[Constants.HeaderConstants.PopReceipt]; - } - - /// - /// Extracts the next visibility time from a web response header. - /// - /// The web response. - /// The time of next visibility stored in the header of the response. - public static DateTime GetNextVisibleTime(HttpWebResponse response) - { - CommonUtility.AssertNotNull("response", response); - - return DateTime.Parse( - response.Headers[Constants.HeaderConstants.NextVisibleTime], - System.Globalization.DateTimeFormatInfo.InvariantInfo, - System.Globalization.DateTimeStyles.AdjustToUniversal); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpWebRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpWebRequestFactory.cs deleted file mode 100644 index be98a4052eeec..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Queue/Protocol/QueueHttpWebRequestFactory.cs +++ /dev/null @@ -1,341 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Net; - - /// - /// A factory class for constructing a web request to manage queues in the Queue service. - /// - public static class QueueHttpWebRequestFactory - { - /// - /// Creates a web request to get the properties of the Queue service. - /// - /// The absolute URI to the Queue service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to get the Queue service properties. - /// - public static HttpWebRequest GetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.GetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Creates a web request to set the properties of the Queue service. - /// - /// The absolute URI to the Queue service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to set the Queue service properties. - /// - public static HttpWebRequest SetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.SetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Writes Queue service properties to a stream, formatted in XML. - /// - /// The service properties to format and write to the stream. - /// The stream to which the formatted properties are to be written. - public static void WriteServiceProperties(ServiceProperties properties, Stream outputStream) - { - CommonUtility.AssertNotNull("properties", properties); - - properties.WriteServiceProperties(outputStream); - } - - /// - /// Constructs a web request to create a new queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Create(Uri uri, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.Create(uri, timeout, null, operationContext); - } - - /// - /// Constructs a web request to delete the queue and all of the messages within it. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest Delete(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.Delete(uri, null, timeout, operationContext); - return request; - } - - /// - /// Constructs a web request to clear all messages in the queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest ClearMessages(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.Delete(uri, null, timeout, operationContext); - return request; - } - - /// - /// Generates a web request to return the user-defined metadata for this queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetMetadata(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.GetMetadata(uri, timeout, null, operationContext); - return request; - } - - /// - /// Generates a web request to set user-defined metadata for the queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest SetMetadata(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.SetMetadata(uri, timeout, null, operationContext); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpWebRequest request, IDictionary metadata) - { - HttpWebRequestFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpWebRequest request, string name, string value) - { - HttpWebRequestFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to return a listing of all queues in this storage account. - /// - /// The absolute URI for the account. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// Additional details to return with the listing. - /// An object for tracking the current operation. - /// A web request for the specified operation. - public static HttpWebRequest List(Uri uri, int? timeout, ListingContext listingContext, QueueListingDetails detailsIncluded, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - } - - if ((detailsIncluded & QueueListingDetails.Metadata) != 0) - { - builder.Add("include", "metadata"); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest GetAcl(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.GetAcl(uri, null, timeout, operationContext); - return request; - } - - /// - /// Constructs a web request to set the ACL for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - public static HttpWebRequest SetAcl(Uri uri, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = HttpWebRequestFactory.SetAcl(uri, null, timeout, operationContext); - return request; - } - - /// - /// Constructs a web request to add a message for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// The message time-to-live, in seconds. - /// The visibility timeout, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest AddMessage(Uri uri, int? timeout, int? timeToLiveInSeconds, int? visibilityTimeoutInSeconds, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - if (timeToLiveInSeconds != null) - { - builder.Add(Constants.QueryConstants.MessageTimeToLive, timeToLiveInSeconds.ToString()); - } - - if (visibilityTimeoutInSeconds != null) - { - builder.Add(Constants.QueryConstants.VisibilityTimeout, visibilityTimeoutInSeconds.ToString()); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Post, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to update a message. - /// - /// The absolute URI to the message to update. - /// The server timeout interval, in seconds. - /// The pop receipt of the message. - /// The length of time from now during which the message will be invisible, in seconds. - /// An object for tracking the current operation. - /// A web request for the update operation. - public static HttpWebRequest UpdateMessage(Uri uri, int? timeout, string popReceipt, int visibilityTimeoutInSeconds, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - builder.Add(Constants.QueryConstants.PopReceipt, popReceipt); - builder.Add(Constants.QueryConstants.VisibilityTimeout, visibilityTimeoutInSeconds.ToString(CultureInfo.InvariantCulture)); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to update a message. - /// - /// The absolute URI to the message to update. - /// The server timeout interval, in seconds. - /// The pop receipt of the message. - /// An object for tracking the current operation. - /// A web request for the update operation. - public static HttpWebRequest DeleteMessage(Uri uri, int? timeout, string popReceipt, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.PopReceipt, popReceipt); - - HttpWebRequest request = HttpWebRequestFactory.Delete(uri, builder, timeout, operationContext); - return request; - } - - /// - /// Constructs a web request to get messages for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// The number of messages. - /// The visibility timeout. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest GetMessages(Uri uri, int? timeout, int numberOfMessages, TimeSpan? visibilityTimeout, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - builder.Add(Constants.QueryConstants.NumOfMessages, numberOfMessages.ToString(CultureInfo.InvariantCulture)); - - if (visibilityTimeout != null) - { - builder.Add(Constants.QueryConstants.VisibilityTimeout, visibilityTimeout.Value.RoundUpToSeconds().ToString(CultureInfo.InvariantCulture)); - } - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to peeks messages for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// The number of messages. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest PeekMessages(Uri uri, int? timeout, int numberOfMessages, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.HeaderConstants.PeekOnly, Constants.HeaderConstants.TrueHeader); - - builder.Add(Constants.QueryConstants.NumOfMessages, numberOfMessages.ToString(CultureInfo.InvariantCulture)); - - HttpWebRequest request = HttpWebRequestFactory.CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpResponseParsers.cs deleted file mode 100644 index c91e014aaa040..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpResponseParsers.cs +++ /dev/null @@ -1,92 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Executor; - using System; - using System.Collections.Generic; - using System.Net; - - internal static partial class HttpResponseParsers - { - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode expectedStatusCode, HttpWebResponse resp, T retVal, StorageCommandBase cmd, Exception ex) - { - return ProcessExpectedStatusCodeNoException(expectedStatusCode, resp != null ? resp.StatusCode : HttpStatusCode.Unused, retVal, cmd, ex); - } - - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode[] expectedStatusCodes, HttpWebResponse resp, T retVal, StorageCommandBase cmd, Exception ex) - { - return ProcessExpectedStatusCodeNoException(expectedStatusCodes, resp != null ? resp.StatusCode : HttpStatusCode.Unused, retVal, cmd, ex); - } - - /// - /// Gets an ETag from a response. - /// - /// The web response. - /// A quoted ETag string. - internal static string GetETag(HttpWebResponse response) - { - return response.Headers[HttpResponseHeader.ETag]; - } - -#if WINDOWS_PHONE - /// - /// Gets the Last-Modified date and time from a response. - /// - /// The web response. - /// A that indicates the last modified date and time. - internal static DateTimeOffset? GetLastModified(HttpWebResponse response) - { - string lastModified = response.Headers[HttpResponseHeader.LastModified]; - return string.IsNullOrEmpty(lastModified) ? (DateTimeOffset?)null : DateTimeOffset.Parse(lastModified); - } -#endif - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - internal static IDictionary GetMetadata(HttpWebResponse response) - { - return GetMetadataOrProperties(response, Constants.HeaderConstants.PrefixForStorageMetadata); - } - - /// - /// Gets the metadata or properties. - /// - /// The response from server. - /// The prefix for all the headers. - /// A of the headers with the prefix. - private static IDictionary GetMetadataOrProperties(HttpWebResponse response, string prefix) - { - IDictionary nameValues = new Dictionary(); - int prefixLength = prefix.Length; - - foreach (string header in response.Headers.AllKeys) - { - if (header.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - nameValues[header.Substring(prefixLength)] = response.Headers[header]; - } - } - - return nameValues; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpWebRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpWebRequestFactory.cs deleted file mode 100644 index 9d1678c01cf7a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/HttpWebRequestFactory.cs +++ /dev/null @@ -1,301 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Net; - - internal static class HttpWebRequestFactory - { - /// - /// Creates the web request. - /// - /// The HTTP method. - /// The request URI. - /// The timeout. - /// An object of type , containing additional parameters to add to the URI query string. - /// An object for tracking the current operation. - /// - /// A web request for performing the operation. - /// - [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "operationContext")] - internal static HttpWebRequest CreateWebRequest(string method, Uri uri, int? timeout, UriQueryBuilder builder, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - if (timeout.HasValue && timeout.Value > 0) - { - builder.Add("timeout", timeout.Value.ToString(CultureInfo.InvariantCulture)); - } - -#if WINDOWS_PHONE - // Windows Phone does not allow the caller to disable caching, so a random GUID - // is added to every URI to make it look a different request. - builder.Add("randomguid", Guid.NewGuid().ToString("N")); -#endif - - Uri uriRequest = builder.AddToUri(uri); - - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriRequest); - request.Method = method; - - // Set the Content-Length of requests to 0 by default. If we do not upload - // a body, signing requires it to be 0. On Windows Phone, all requests except - // GET need this. On desktop, however, only PUT requests need it. -#if !WINDOWS_PHONE - if (method.Equals(WebRequestMethods.Http.Put, StringComparison.OrdinalIgnoreCase)) -#else - if (!method.Equals(WebRequestMethods.Http.Get, StringComparison.OrdinalIgnoreCase)) -#endif - { - request.ContentLength = 0; - } - - request.UserAgent = Constants.HeaderConstants.UserAgent; - request.Headers[Constants.HeaderConstants.StorageVersionHeader] = Constants.HeaderConstants.TargetStorageVersion; - -#if !WINDOWS_PHONE - request.KeepAlive = true; - - // Disable the Expect 100-Continue - request.ServicePoint.Expect100Continue = false; -#endif - - return request; - } - - /// - /// Creates the specified URI. - /// - /// The URI to create. - /// The timeout. - /// The builder. - /// An object for tracking the current operation. - /// A web request for performing the operation. - internal static HttpWebRequest Create(Uri uri, int? timeout, UriQueryBuilder builder, OperationContext operationContext) - { - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a cloud resource. - /// - /// The absolute URI to the resource. - /// The server timeout interval. - /// An optional query builder to use. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - internal static HttpWebRequest GetAcl(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "acl"); - - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Constructs a web request to set the ACL for a cloud resource. - /// - /// The absolute URI to the resource. - /// The server timeout interval. - /// An optional query builder to use. - /// An object for tracking the current operation. - /// A web request to use to perform the operation. - internal static HttpWebRequest SetAcl(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "acl"); - - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Gets the properties. - /// - /// The URI to query. - /// The timeout. - /// The builder. - /// An object for tracking the current operation. - /// A web request for performing the operation. - internal static HttpWebRequest GetProperties(Uri uri, int? timeout, UriQueryBuilder builder, OperationContext operationContext) - { - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Head, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Gets the metadata. - /// - /// The blob Uri. - /// The timeout. - /// The builder. - /// An object for tracking the current operation. - /// A web request for performing the operation. - internal static HttpWebRequest GetMetadata(Uri uri, int? timeout, UriQueryBuilder builder, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "metadata"); - - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Head, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Sets the metadata. - /// - /// The blob Uri. - /// The timeout. - /// The builder. - /// An object for tracking the current operation. - /// A web request for performing the operation. - internal static HttpWebRequest SetMetadata(Uri uri, int? timeout, UriQueryBuilder builder, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "metadata"); - - HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - return request; - } - - /// - /// Adds the metadata. - /// - /// The request. - /// The metadata. - internal static void AddMetadata(HttpWebRequest request, IDictionary metadata) - { - if (metadata != null) - { - foreach (KeyValuePair entry in metadata) - { - AddMetadata(request, entry.Key, entry.Value); - } - } - } - - /// - /// Adds the metadata. - /// - /// The request. - /// The metadata name. - /// The metadata value. - internal static void AddMetadata(HttpWebRequest request, string name, string value) - { - CommonUtility.AssertNotNullOrEmpty("value", value); - request.Headers.Add("x-ms-meta-" + name, value); - } - - /// - /// Deletes the specified URI. - /// - /// The URI of the resource to delete. - /// The timeout. - /// The builder. - /// An object for tracking the current operation. - /// A web request for performing the operation. - internal static HttpWebRequest Delete(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - HttpWebRequest request = CreateWebRequest("DELETE", uri, timeout, builder, operationContext); - return request; - } - - /// - /// Creates a web request to get the properties of the service. - /// - /// The absolute URI to the service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval. - /// An object for tracking the current operation. - /// - /// A web request to get the service properties. - /// - internal static HttpWebRequest GetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "properties"); - builder.Add(Constants.QueryConstants.ResourceType, "service"); - - return CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); - } - - /// - /// Creates a web request to set the properties of the service. - /// - /// The absolute URI to the service. - /// The builder. - /// The server timeout interval. - /// An object for tracking the current operation. - /// - /// A web request to set the service properties. - /// - internal static HttpWebRequest SetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "properties"); - builder.Add(Constants.QueryConstants.ResourceType, "service"); - - return CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); - } - - /// - /// Generates a query builder for building service requests. - /// - /// A for building service requests. - internal static UriQueryBuilder GetServiceUriQueryBuilder() - { - UriQueryBuilder uriBuilder = new UriQueryBuilder(); - uriBuilder.Add(Constants.QueryConstants.ResourceType, "service"); - return uriBuilder; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/WebRequestExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/WebRequestExtensions.cs deleted file mode 100644 index 751ff8a310789..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Shared/Protocol/WebRequestExtensions.cs +++ /dev/null @@ -1,193 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Globalization; - using System.Net; - - internal static class WebRequestExtensions - { - /// - /// Adds the lease id. - /// - /// The request. - /// The lease id. - internal static void AddLeaseId(this HttpWebRequest request, string leaseId) - { - if (leaseId != null) - { - request.AddOptionalHeader("x-ms-lease-id", leaseId); - } - } - - /// - /// Adds an optional header to a request. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - internal static void AddOptionalHeader(this HttpWebRequest request, string name, string value) - { - if (!string.IsNullOrEmpty(value)) - { - request.Headers.Add(name, value); - } - } - - /// - /// Adds an optional header to a request. - /// - /// The web request. - /// The header name. - /// The header value. - internal static void AddOptionalHeader(this HttpWebRequest request, string name, int? value) - { - if (value.HasValue) - { - request.Headers.Add(name, value.Value.ToString(CultureInfo.InvariantCulture)); - } - } - - /// - /// Adds an optional header to a request. - /// - /// The web request. - /// The header name. - /// The header value. - internal static void AddOptionalHeader(this HttpWebRequest request, string name, long? value) - { - if (value.HasValue) - { - request.Headers.Add(name, value.Value.ToString(CultureInfo.InvariantCulture)); - } - } - - /// - /// Applies the lease condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyLeaseId(this HttpWebRequest request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.LeaseId)) - { - request.Headers[Constants.HeaderConstants.LeaseIdHeader] = accessCondition.LeaseId; - } - } - } - - /// - /// Applies the sequence number condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplySequenceNumberCondition(this HttpWebRequest request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberLEHeader, accessCondition.IfSequenceNumberLessThanOrEqual); - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberLTHeader, accessCondition.IfSequenceNumberLessThan); - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberEqHeader, accessCondition.IfSequenceNumberEqual); - } - } - - /// - /// Applies the condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyAccessCondition(this HttpWebRequest request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - request.Headers[HttpRequestHeader.IfMatch] = accessCondition.IfMatchETag; - } - - if (!string.IsNullOrEmpty(accessCondition.IfNoneMatchETag)) - { - request.Headers[HttpRequestHeader.IfNoneMatch] = accessCondition.IfNoneMatchETag; - } - - if (accessCondition.IfModifiedSinceTime.HasValue) - { -#if WINDOWS_PHONE - request.Headers[HttpRequestHeader.IfModifiedSince] = - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfModifiedSinceTime.Value); -#else - // Not using this property will cause Restricted property exception to be thrown - request.IfModifiedSince = accessCondition.IfModifiedSinceTime.Value.UtcDateTime; -#endif - } - - if (accessCondition.IfNotModifiedSinceTime.HasValue) - { - request.Headers[HttpRequestHeader.IfUnmodifiedSince] = - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfNotModifiedSinceTime.Value); - } - - request.ApplyLeaseId(accessCondition); - } - } - - /// - /// Applies the condition for a source blob to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyAccessConditionToSource(this HttpWebRequest request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - request.Headers[Constants.HeaderConstants.SourceIfMatchHeader] = accessCondition.IfMatchETag; - } - - if (!string.IsNullOrEmpty(accessCondition.IfNoneMatchETag)) - { - request.Headers[Constants.HeaderConstants.SourceIfNoneMatchHeader] = accessCondition.IfNoneMatchETag; - } - - if (accessCondition.IfModifiedSinceTime.HasValue) - { - request.Headers[Constants.HeaderConstants.SourceIfModifiedSinceHeader] = - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfModifiedSinceTime.Value); - } - - if (accessCondition.IfNotModifiedSinceTime.HasValue) - { - request.Headers[Constants.HeaderConstants.SourceIfUnmodifiedSinceHeader] = - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfNotModifiedSinceTime.Value); - } - - if (!string.IsNullOrEmpty(accessCondition.LeaseId)) - { - throw new InvalidOperationException(SR.LeaseConditionOnSource); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTable.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTable.cs deleted file mode 100644 index ec1faaa6149ff..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTable.cs +++ /dev/null @@ -1,1970 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Queryable; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a Windows Azure table. - /// - public sealed partial class CloudTable - { - #region TableOperation Execute Methods -#if SYNC - /// - /// Executes the operation on a table, using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A containing the result of executing the operation on the table. - [DoesServiceRequest] - public TableResult Execute(TableOperation operation, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("operation", operation); - - return operation.Execute(this.ServiceClient, this.Name, requestOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous table operation. - /// - /// A object that represents the operation to perform. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecute(TableOperation operation, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("batch", operation); - return this.BeginExecute(operation, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous table operation using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecute(TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("operation", operation); - - return operation.BeginExecute(this.ServiceClient, this.Name, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous table operation. - /// - /// An that references the pending asynchronous operation. - /// A containing the result executing the operation on the table. - public TableResult EndExecute(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous table operation using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExecuteAsync(TableOperation operation) - { - return this.ExecuteAsync(operation, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous table operation using the specified and . - /// - /// A object that represents the operation to perform. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExecuteAsync(TableOperation operation, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecute, this.EndExecute, operation, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous table operation using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExecuteAsync(TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteAsync(operation, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous table operation using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExecuteAsync(TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecute, this.EndExecute, operation, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region TableBatchOperation Execute Methods -#if SYNC - /// - /// Executes a batch operation on a table as an atomic operation, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection of objects that contains the results, in order, of each operation in the on the table. - [DoesServiceRequest] - public IList ExecuteBatch(TableBatchOperation batch, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("batch", batch); - return batch.Execute(this.ServiceClient, this.Name, requestOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to execute a batch of operations on a table. - /// - /// The object representing the operations to execute on the table. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteBatch(TableBatchOperation batch, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("batch", batch); - return this.BeginExecuteBatch(batch, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to execute a batch of operations on a table, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteBatch(TableBatchOperation batch, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("batch", batch); - - return batch.BeginExecute(this.ServiceClient, this.Name, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous batch of operations on a table. - /// - /// An that references the pending asynchronous operation. - /// A enumerable collection of type that contains the results, in order, of each operation in the on the table. - public IList EndExecuteBatch(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to execute a batch of operations on a table, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteBatchAsync(TableBatchOperation batch) - { - return this.ExecuteBatchAsync(batch, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a batch of operations on a table, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteBatchAsync(TableBatchOperation batch, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteBatch, this.EndExecuteBatch, batch, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a batch of operations on a table, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteBatchAsync(TableBatchOperation batch, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteBatchAsync(batch, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a batch of operations on a table, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteBatchAsync(TableBatchOperation batch, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteBatch, this.EndExecuteBatch, batch, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region TableQuery Execute Methods - #region NonGeneric -#if SYNC - /// - /// Executes a query on a table, using the specified and . - /// - /// A representing the query to execute. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection of objects, representing table entities returned by the query. - [DoesServiceRequest] - public IEnumerable ExecuteQuery(TableQuery query, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("query", query); - return query.Execute(this.ServiceClient, this.Name, requestOptions, operationContext); - } - - /// - /// Executes a query in segmented mode with the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A object containing the results of executing the query. - [DoesServiceRequest] - public TableQuerySegment ExecuteQuerySegmented(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("query", query); - return query.ExecuteQuerySegmented(token, this.ServiceClient, this.Name, requestOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous segmented query operation using the specified continuation token. - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, TableContinuationToken token, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("query", query); - return this.BeginExecuteQuerySegmented(query, token, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to query a table in segmented mode using the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("query", query); - return query.BeginExecuteQuerySegmented(token, this.ServiceClient, this.Name, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous segmented query operation. - /// - /// An that references the pending asynchronous operation. - /// A object containing the results of executing the query. - public TableQuerySegment EndExecuteQuerySegmented(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token) - { - return this.ExecuteQuerySegmentedAsync(query, token, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, token, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, token, requestOptions, operationContext, cancellationToken); - } -#endif - - #region With Resolver -#if SYNC - /// - /// Executes a query on a table, using the specified and , applying the to the result. - /// - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection, containing the projection into type TResult, of the results of executing the query. - [DoesServiceRequest] - public IEnumerable ExecuteQuery(TableQuery query, EntityResolver resolver, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - return query.Execute(this.ServiceClient, this.Name, resolver, requestOptions, operationContext); - } - - /// - /// Executes a query in segmented mode with the specified continuation token, , and . - /// - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A object containing the results of executing the query. - [DoesServiceRequest] - public TableQuerySegment ExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - CommonUtility.AssertNotNull("query", query); - return query.ExecuteQuerySegmented(token, this.ServiceClient, this.Name, resolver, requestOptions, operationContext); - } -#endif - - /// - /// Begins an asynchronous segmented query operation using the specified continuation token. - /// - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, AsyncCallback callback, object state) - { - return this.BeginExecuteQuerySegmented(query, resolver, token, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - return query.BeginExecuteQuerySegmented(token, this.ServiceClient, this.Name, resolver, requestOptions, operationContext, callback, state); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token) - { - return this.ExecuteQuerySegmentedAsync(query, resolver, token, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, resolver, token, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, resolver, token, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - #endregion - - #region Generic - /// - /// A factory method that creates a query that can be modified using LINQ. The query may be subsequently executed using one of the execution methods available for , - /// such as , , or . - /// - /// The entity type of the query. - /// A object, specialized for type TElement, that may subsequently be executed. - /// - /// The namespace includes extension methods for the object, - /// including , , and . To use these methods, include a using - /// statement that references the namespace. - /// - public TableQuery CreateQuery() where TElement : ITableEntity, new() - { - return new TableQuery(this); - } - -#if SYNC - /// - /// Executes a query on a table, using the specified and . - /// - /// The entity type of the query. - /// A TableQuery instance specifying the table to query and the query parameters to use, specialized for a type T implementing TableEntity. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection, specialized for type TElement, of the results of executing the query. - [DoesServiceRequest] - public IEnumerable ExecuteQuery(TableQuery query, TableRequestOptions requestOptions = null, OperationContext operationContext = null) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - if (query.Provider != null) - { - return query.Execute(requestOptions, operationContext); - } - else - { - return query.ExecuteInternal(this.ServiceClient, this.Name, requestOptions, operationContext); - } - } - - /// - /// Queries a table in segmented mode using the specified continuation token, , and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A , specialized for type TElement, containing the results of executing the query. - [DoesServiceRequest] - public TableQuerySegment ExecuteQuerySegmented(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions = null, OperationContext operationContext = null) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - if (query.Provider != null) - { - return query.ExecuteSegmented(token, requestOptions, operationContext); - } - else - { - return query.ExecuteQuerySegmentedInternal(token, this.ServiceClient, this.Name, requestOptions, operationContext); - } - } -#endif - - /// - /// Begins an asynchronous operation to query a table in segmented mode, using the specified continuation token. - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, TableContinuationToken token, AsyncCallback callback, object state) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - return this.BeginExecuteQuerySegmented(query, token, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to query a table in segmented mode using the specified continuation token and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - if (query.Provider != null) - { - return query.BeginExecuteSegmented(token, requestOptions, operationContext, callback, state); - } - else - { - return query.BeginExecuteQuerySegmentedInternal(token, this.ServiceClient, this.Name, requestOptions, operationContext, callback, state); - } - } - - /// - /// Ends an asynchronous segmented table query operation. - /// - /// The type of the results to be returned. Can be the entity type specified in the Begin or the result type of the resolver - /// An that references the pending asynchronous operation. - /// A containing the results of executing the query. - public TableQuerySegment EndExecuteQuerySegmented(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token) where TElement : ITableEntity, new() - { - return this.ExecuteQuerySegmentedAsync(query, token, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, CancellationToken cancellationToken) where TElement : ITableEntity, new() - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, token, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) where TElement : ITableEntity, new() - { - return this.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to query a table in segmented mode using the specified continuation token and . - /// - /// The entity type of the query. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) where TElement : ITableEntity, new() - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, token, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region With Resolvers -#if SYNC - /// - /// Executes a query, using the specified and , applying the to the result. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection, containing the projection into type TResult, of the results of executing the query. - [DoesServiceRequest] - public IEnumerable ExecuteQuery(TableQuery query, EntityResolver resolver, TableRequestOptions requestOptions = null, OperationContext operationContext = null) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - if (query.Provider != null) - { - return TableQueryableExtensions.Resolve(query, resolver).Execute(requestOptions, operationContext); - } - else - { - return query.ExecuteInternal(this.ServiceClient, this.Name, resolver, requestOptions, operationContext); - } - } - - /// - /// Executes a query in segmented mode with the specified continuation token, using the specified and , applying the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A containing the projection into type TResult of the results of executing the query. - [DoesServiceRequest] - public TableQuerySegment ExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions = null, OperationContext operationContext = null) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - if (query.Provider != null) - { - return TableQueryableExtensions.Resolve(query, resolver).ExecuteSegmented(token, requestOptions, operationContext); - } - else - { - return query.ExecuteQuerySegmentedInternal(token, this.ServiceClient, this.Name, resolver, requestOptions, operationContext); - } - } - -#endif - /// - /// Begins an asynchronous operation to query a table in segmented mode, using the specified and continuation token. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, AsyncCallback callback, object state) where TElement : ITableEntity, new() - { - return this.BeginExecuteQuerySegmented(query, resolver, token, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteQuerySegmented(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) where TElement : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - if (query.Provider != null) - { - return TableQueryableExtensions.Resolve(query, resolver).BeginExecuteSegmented(token, requestOptions, operationContext, callback, state); - } - else - { - return query.BeginExecuteQuerySegmentedInternal(token, this.ServiceClient, this.Name, resolver, requestOptions, operationContext, callback, state); - } - } - - /// - /// Ends an asynchronous segmented table query operation. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// An that references the pending asynchronous operation. - /// A containing the projection into type TResult of the results of executing the query. - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Reveiewed.")] - public TableQuerySegment EndExecuteQuerySegmented(IAsyncResult asyncResult) where TElement : ITableEntity, new() - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token) where TElement : ITableEntity, new() - { - return this.ExecuteQuerySegmentedAsync(query, resolver, token, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, CancellationToken cancellationToken) where TElement : ITableEntity, new() - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, resolver, token, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) where TElement : ITableEntity, new() - { - return this.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query in segmented mode with the specified continuation token, , and , applies the to the results. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// A instance specifying the table to query and the query parameters to use, specialized for a type TElement. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteQuerySegmentedAsync(TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) where TElement : ITableEntity, new() - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteQuerySegmented, this.EndExecuteQuerySegmented, query, resolver, token, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #endregion - - #region Create -#if SYNC - /// - /// Creates a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - [DoesServiceRequest] - public void Create(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Insert); - operation.IsTableEntity = true; - - operation.Execute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext); - } -#endif - /// - /// Begins an asynchronous operation to create a table. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(AsyncCallback callback, object state) - { - return this.BeginCreate(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreate(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Insert); - operation.IsTableEntity = true; - - return operation.BeginExecute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to create a table. - /// - /// An that references the pending asynchronous operation. - public void EndCreate(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a table. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync() - { - return this.CreateAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.CreateAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginCreate, this.EndCreate, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region CreateIfNotExists -#if SYNC - /// - /// Creates the table if it does not already exist. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if table was created; otherwise, false. - [DoesServiceRequest] - public bool CreateIfNotExists(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - if (this.Exists(modifiedOptions, operationContext)) - { - return false; - } - else - { - try - { - this.Create(modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == TableErrorCodeStrings.TableAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } - } -#endif - - /// - /// Begins an asynchronous operation to create a table if it does not already exist. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(AsyncCallback callback, object state) - { - return this.BeginCreateIfNotExists(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to create a table if it does not already exist. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginCreateIfNotExists(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult retResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext - }; - - lock (retResult.CancellationLockerObject) - { - ICancellableAsyncResult currentRes = this.BeginExists(modifiedOptions, operationContext, this.CreateIfNotExistHandler, retResult); - retResult.CancelDelegate = currentRes.Cancel; - - // Check if cancellation was requested prior to begin - if (retResult.CancelRequested) - { - retResult.CancelDelegate(); - } - } - - return retResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void CreateIfNotExistHandler(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = asyncResult.AsyncState as StorageAsyncResult; - bool exists = false; - - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously); - - try - { - exists = this.EndExists(asyncResult); - - if (exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - ICancellableAsyncResult currentRes = this.BeginCreate( - (TableRequestOptions)storageAsyncResult.RequestOptions, - storageAsyncResult.OperationContext, - createRes => - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(storageAsyncResult.CompletedSynchronously); - - try - { - this.EndCreate(createRes); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == TableErrorCodeStrings.TableAlreadyExists)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception createEx) - { - storageAsyncResult.OnComplete(createEx); - } - }, - null); - - storageAsyncResult.CancelDelegate = currentRes.Cancel; - } - } - catch (Exception ex) - { - storageAsyncResult.OnComplete(ex); - } - } - } - - /// - /// Ends an asynchronous operation to determine whether a table exists. - /// - /// An that references the pending asynchronous operation. - /// true if table exists; otherwise, false. - public bool EndCreateIfNotExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to create a table if it does not already exist. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table if it does not already exist. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table if it does not already exist. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.CreateIfNotExistsAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to create a table if it does not already exist. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task CreateIfNotExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginCreateIfNotExists, this.EndCreateIfNotExists, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region Delete -#if SYNC - /// - /// Deletes a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - [DoesServiceRequest] - public void Delete(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Delete); - operation.IsTableEntity = true; - - operation.Execute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext); - } -#endif - /// - /// Begins an asynchronous operation to delete a table. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(AsyncCallback callback, object state) - { - return this.BeginDelete(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDelete(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Delete); - operation.IsTableEntity = true; - - return operation.BeginExecute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to delete a table. - /// - /// An that references the pending asynchronous operation. - public void EndDelete(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete a table. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync() - { - return this.DeleteAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a table. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.DeleteAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete a table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginDelete, this.EndDelete, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region DeleteIfExists -#if SYNC - /// - /// Deletes the table if it exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if the table was deleted; otherwise, false. - [DoesServiceRequest] - public bool DeleteIfExists(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - if (!this.Exists(modifiedOptions, operationContext)) - { - return false; - } - else - { - try - { - this.Delete(modifiedOptions, operationContext); - return true; - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == TableErrorCodeStrings.TableNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } - } -#endif - - /// - /// Begins an asynchronous operation to delete the table if it exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(AsyncCallback callback, object state) - { - return this.BeginDeleteIfExists(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to delete the table if it exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginDeleteIfExists(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - StorageAsyncResult retResult = new StorageAsyncResult(callback, state) - { - RequestOptions = modifiedOptions, - OperationContext = operationContext - }; - - lock (retResult.CancellationLockerObject) - { - ICancellableAsyncResult currentRes = this.BeginExists(modifiedOptions, operationContext, this.DeleteIfExistsHandler, retResult); - retResult.CancelDelegate = currentRes.Cancel; - - // Check if cancellation was requested prior to begin - if (retResult.CancelRequested) - { - retResult.CancelDelegate(); - } - } - - return retResult; - } - - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Needed to ensure exceptions are not thrown on threadpool threads.")] - private void DeleteIfExistsHandler(IAsyncResult asyncResult) - { - StorageAsyncResult storageAsyncResult = asyncResult.AsyncState as StorageAsyncResult; - bool exists = false; - lock (storageAsyncResult.CancellationLockerObject) - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(asyncResult.CompletedSynchronously); - - try - { - exists = this.EndExists(asyncResult); - - if (!exists) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - ICancellableAsyncResult currentRes = this.BeginDelete( - (TableRequestOptions)storageAsyncResult.RequestOptions, - storageAsyncResult.OperationContext, - (deleteRes) => - { - storageAsyncResult.CancelDelegate = null; - storageAsyncResult.UpdateCompletedSynchronously(deleteRes.CompletedSynchronously); - - try - { - this.EndDelete(deleteRes); - storageAsyncResult.Result = true; - storageAsyncResult.OnComplete(); - } - catch (StorageException e) - { - if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - if ((e.RequestInformation.ExtendedErrorInformation == null) || - (e.RequestInformation.ExtendedErrorInformation.ErrorCode == TableErrorCodeStrings.TableNotFound)) - { - storageAsyncResult.Result = false; - storageAsyncResult.OnComplete(); - } - else - { - storageAsyncResult.OnComplete(e); - } - } - else - { - storageAsyncResult.OnComplete(e); - } - } - catch (Exception createEx) - { - storageAsyncResult.OnComplete(createEx); - } - }, - null); - - storageAsyncResult.CancelDelegate = currentRes.Cancel; - } - } - catch (Exception ex) - { - storageAsyncResult.OnComplete(ex); - } - } - } - - /// - /// Ends an asynchronous operation to delete the table if it exists. - /// - /// An that references the pending asynchronous operation. - /// true if the table was deleted; otherwise, false. - public bool EndDeleteIfExists(IAsyncResult asyncResult) - { - StorageAsyncResult res = asyncResult as StorageAsyncResult; - CommonUtility.AssertNotNull("AsyncResult", res); - res.End(); - return res.Result; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to delete the table if it exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the table if it exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the table if it exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.DeleteIfExistsAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to delete the table if it exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task DeleteIfExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginDeleteIfExists, this.EndDeleteIfExists, requestOptions, operationContext, cancellationToken); - } -#endif - #endregion - - #region Exists -#if SYNC - /// - /// Checks whether the table exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if table exists; otherwise, false. - [DoesServiceRequest] - public bool Exists(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Retrieve); - operation.IsTableEntity = true; - - TableResult res = operation.Execute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext); - - // Only other option is not found, other status codes will throw prior to this. - return res.HttpStatusCode == (int)HttpStatusCode.OK; - } -#endif - - /// - /// Begins an asynchronous operation to determine whether a table exists. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(AsyncCallback callback, object state) - { - return this.BeginExists(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to determine whether a table exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExists(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Retrieve); - operation.IsTableEntity = true; - - return operation.BeginExecute(this.ServiceClient, TableConstants.TableServiceTablesName, requestOptions, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to determine whether a table exists. - /// - /// An that references the pending asynchronous operation. - /// true if table exists; otherwise, false. - public bool EndExists(IAsyncResult asyncResult) - { - TableResult res = Executor.EndExecuteAsync(asyncResult); - - // Only other option is not found, other status codes will throw prior to this. - return res.HttpStatusCode == (int)HttpStatusCode.OK; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to determine whether a table exists. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync() - { - return this.ExistsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to determine whether a table exists. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to determine whether a table exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExistsAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to determine whether a table exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExists, this.EndExists, requestOptions, operationContext, cancellationToken); - } -#endif - - #endregion - - #region Permissions -#if SYNC - /// - /// Gets the permissions settings for the table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The table's permissions. - [DoesServiceRequest] - public TablePermissions GetPermissions(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return Executor.ExecuteSync(this.GetAclImpl(requestOptions), requestOptions.RetryPolicy, operationContext); - } -#endif - - /// - /// Begins an asynchronous request to get the permissions settings for the table. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(AsyncCallback callback, object state) - { - return this.BeginGetPermissions(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to get the permissions settings for the table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetPermissions(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.GetAclImpl(requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to get the permissions settings for the table. - /// - /// An that references the pending asynchronous operation. - /// The table's permissions. - public TablePermissions EndGetPermissions(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the table. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync() - { - return this.GetPermissionsAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the table. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.GetPermissionsAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to get the permissions settings for the table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetPermissionsAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetPermissions, this.EndGetPermissions, requestOptions, operationContext, cancellationToken); - } -#endif - - private RESTCommand GetAclImpl(TableRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - retCmd.BuildRequestDelegate = TableHttpWebRequestFactory.GetAcl; - retCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - retCmd.RetrieveResponseStream = true; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - retCmd.PostProcessResponse = this.ParseGetAcl; - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - private TablePermissions ParseGetAcl(RESTCommand cmd, HttpWebResponse resp, OperationContext ctx) - { - TablePermissions tableAcl = new TablePermissions(); - - // Get the policies from the web response. - TableHttpWebResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, tableAcl); - - return tableAcl; - } - -#if SYNC - /// - /// Sets the permissions settings for the table. - /// - /// A object that represents the permissions to set. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - [DoesServiceRequest] - public void SetPermissions(TablePermissions permissions, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - Executor.ExecuteSync(this.SetAclImpl(permissions, requestOptions), requestOptions.RetryPolicy, operationContext); - } -#endif - - /// - /// Begins an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(TablePermissions permissions, AsyncCallback callback, object state) - { - return this.BeginSetPermissions(permissions, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetPermissions(TablePermissions permissions, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync( - this.SetAclImpl(permissions, requestOptions), - requestOptions.RetryPolicy, - operationContext, - callback, - state); - } - - /// - /// Returns the asynchronous result of the request to get the permissions settings for the table. - /// - /// An that references the pending asynchronous operation. - public void EndSetPermissions(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(TablePermissions permissions) - { - return this.SetPermissionsAsync(permissions, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(TablePermissions permissions, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(TablePermissions permissions, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.SetPermissionsAsync(permissions, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous request to set permissions for the table. - /// - /// The permissions to apply to the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetPermissionsAsync(TablePermissions permissions, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetPermissions, this.EndSetPermissions, permissions, requestOptions, operationContext, cancellationToken); - } -#endif - - private RESTCommand SetAclImpl(TablePermissions permissions, TableRequestOptions requestOptions) - { - MultiBufferMemoryStream str = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - TableRequest.WriteSharedAccessIdentifiers(permissions.SharedAccessPolicies, str); - str.Seek(0, SeekOrigin.Begin); - - RESTCommand retCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - retCmd.BuildRequestDelegate = TableHttpWebRequestFactory.SetAcl; - retCmd.SendStream = str; - retCmd.RecoveryAction = RecoveryActions.RewindStream; - retCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTableClient.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTableClient.cs deleted file mode 100644 index 70d19ceee8f07..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/CloudTableClient.cs +++ /dev/null @@ -1,622 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - -#if !WINDOWS_PHONE - using Microsoft.WindowsAzure.Storage.Table.DataServices; -#endif - - /// - /// Provides a client-side logical representation of the Windows Azure Table Service. This client is used to configure and execute requests against the Table Service. - /// - /// The service client encapsulates the base URI for the Table service. If the service client will be used for authenticated access, it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudTableClient - { - private IAuthenticationHandler authenticationHandler; - - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - /// Note that if you are using the legacy Table service API, which is based on WCF Data Services, the authentication scheme used by the TableServiceContext object will always be Shared Key Lite, regardless of the value of this property. - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - if (value != this.authenticationScheme) - { - this.authenticationScheme = value; - this.authenticationHandler = null; - } - } - } - - /// - /// Gets the authentication handler used to sign HTTP requests. - /// - /// The authentication handler. - internal IAuthenticationHandler AuthenticationHandler - { - get - { - IAuthenticationHandler result = this.authenticationHandler; - if (result == null) - { - if (this.Credentials.IsSharedKey) - { - result = new SharedKeyAuthenticationHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - result = new NoOpAuthenticationHandler(); - } - - this.authenticationHandler = result; - } - - return result; - } - } - - #region List Tables -#if SYNC - /// - /// Returns an enumerable collection of tables, which are retrieved lazily, that begin with the specified prefix. - /// - /// The table name prefix. - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// An enumerable collection of tables that are retrieved lazily. - [DoesServiceRequest] - public IEnumerable ListTables(string prefix = null, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - - return CloudTableClient.GenerateListTablesQuery(prefix, null).ExecuteInternal(this, TableConstants.TableServiceTablesName, requestOptions, operationContext).Select( - tbl => new CloudTable(tbl[TableConstants.TableName].StringValue, this)); - } - - /// - /// Returns an enumerable collection of tables in the storage account. - /// - /// A returned by a previous listing operation. - /// An enumerable collection of tables. - [DoesServiceRequest] - public TableResultSegment ListTablesSegmented(TableContinuationToken currentToken) - { - return this.ListTablesSegmented(null, currentToken); - } - - /// - /// Returns an enumerable collection of tables, which are retrieved lazily, that begin with the specified prefix. - /// - /// The table name prefix. - /// A returned by a previous listing operation. - /// An enumerable collection of tables that are retrieved lazily. - [DoesServiceRequest] - public TableResultSegment ListTablesSegmented(string prefix, TableContinuationToken currentToken) - { - return this.ListTablesSegmented(prefix, null, currentToken); - } - - /// - /// Returns an enumerable collection of tables that begin with the specified prefix and that are retrieved lazily. - /// - /// The table name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// An enumerable collection of tables that are retrieved lazily. - [DoesServiceRequest] - public TableResultSegment ListTablesSegmented(string prefix, int? maxResults, TableContinuationToken currentToken, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - TableQuerySegment res = - CloudTableClient.GenerateListTablesQuery(prefix, maxResults).ExecuteQuerySegmentedInternal(currentToken, this, TableConstants.TableServiceTablesName, requestOptions, operationContext); - - List tables = res.Results.Select(tbl => new CloudTable( - tbl.Properties[TableConstants.TableName].StringValue, - this)).ToList(); - - TableResultSegment retSeg = new TableResultSegment(tables) { ContinuationToken = res.ContinuationToken as TableContinuationToken }; - return retSeg; - } -#endif - - /// - /// Begins an asynchronous operation to return a result segment containing a collection of tables - /// in the storage account. - /// - /// A returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListTablesSegmented(TableContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListTablesSegmented(null, currentToken, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A returned by a previous listing operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListTablesSegmented(string prefix, TableContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginListTablesSegmented(prefix, null, currentToken, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// The server timeout, maximum execution time, and retry policies for the operation. - /// An object that provides information on how the operation executed. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginListTablesSegmented(string prefix, int? maxResults, TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - - return CloudTableClient.GenerateListTablesQuery(prefix, maxResults).BeginExecuteQuerySegmentedInternal( - currentToken, - this, - TableConstants.TableServiceTablesName, - requestOptions, - operationContext, - callback, - state); - } - - /// - /// Ends an asynchronous operation to return a result segment containing a collection - /// of tables. - /// - /// An that references the pending asynchronous operation. - /// A result segment containing tables. - public TableResultSegment EndListTablesSegmented(IAsyncResult asyncResult) - { - TableQuerySegment res = Executor.EndExecuteAsync>(asyncResult); - - List tables = res.Results.Select(tbl => new CloudTable( - tbl.Properties[TableConstants.TableName].StringValue, - this)).ToList(); - - TableResultSegment retSeg = new TableResultSegment(tables) { ContinuationToken = res.ContinuationToken }; - return retSeg; - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// A returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(TableContinuationToken currentToken) - { - return this.ListTablesSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// A returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(TableContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListTablesSegmented, this.EndListTablesSegmented, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A returned by a previous listing operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(string prefix, TableContinuationToken currentToken) - { - return this.ListTablesSegmentedAsync(prefix, currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A returned by a previous listing operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(string prefix, TableContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListTablesSegmented, this.EndListTablesSegmented, prefix, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// The server timeout, maximum execution time, and retry policies for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(string prefix, int? maxResults, TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ListTablesSegmentedAsync(prefix, maxResults, currentToken, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to return a result segment containing a collection - /// of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A returned by a previous listing operation. - /// The server timeout, maximum execution time, and retry policies for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task ListTablesSegmentedAsync(string prefix, int? maxResults, TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginListTablesSegmented, this.EndListTablesSegmented, prefix, maxResults, currentToken, requestOptions, operationContext, cancellationToken); - } -#endif - - private static TableQuery GenerateListTablesQuery(string prefix, int? maxResults) - { - TableQuery query = new TableQuery(); - - if (!string.IsNullOrEmpty(prefix)) - { - // Append Max char to end '{' is 1 + 'z' in AsciiTable - string uppperBound = prefix + '{'; - - query = query.Where(TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition(TableConstants.TableName, QueryComparisons.GreaterThanOrEqual, prefix), - TableOperators.And, - TableQuery.GenerateFilterCondition(TableConstants.TableName, QueryComparisons.LessThan, uppperBound))); - } - - if (maxResults.HasValue) - { - query = query.Take(maxResults.Value); - } - - return query; - } - #endregion - - #region Analytics -#if SYNC - /// - /// Gets the service properties for the Table service. - /// - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// The table service properties as a object. - [DoesServiceRequest] - public ServiceProperties GetServiceProperties(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.ExecuteSync(this.GetServicePropertiesImpl(requestOptions), requestOptions.RetryPolicy, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to get the service properties of the Table service. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(AsyncCallback callback, object state) - { - return this.BeginGetServiceProperties(null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to get the service properties of the Table service. - /// - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginGetServiceProperties(TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync(this.GetServicePropertiesImpl(requestOptions), requestOptions.RetryPolicy, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to get the service properties of the Table service. - /// - /// The result returned from a prior call to . - /// The table service properties. - public ServiceProperties EndGetServiceProperties(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to get the service properties of the Table service. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the service properties of the Table service. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to get the service properties of the Table service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.GetServicePropertiesAsync(requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to get the service properties of the Table service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task GetServicePropertiesAsync(TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginGetServiceProperties, this.EndGetServiceProperties, requestOptions, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Sets the service properties of the Table service. - /// - /// The table service properties. - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - [DoesServiceRequest] - public void SetServiceProperties(ServiceProperties properties, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - Executor.ExecuteSync(this.SetServicePropertiesImpl(properties, requestOptions), requestOptions.RetryPolicy, operationContext); - } -#endif - - /// - /// Begins an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, AsyncCallback callback, object state) - { - return this.BeginSetServiceProperties(properties, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user defined object to be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSetServiceProperties(ServiceProperties properties, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return Executor.BeginExecuteAsync(this.SetServicePropertiesImpl(properties, requestOptions), requestOptions.RetryPolicy, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to set the service properties of the Table service. - /// - /// The result returned from a prior call to - public void EndSetServiceProperties(IAsyncResult asyncResult) - { - Executor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.SetServicePropertiesAsync(properties, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to set the service properties of the Table service. - /// - /// The table service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SetServicePropertiesAsync(ServiceProperties properties, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromVoidApm(this.BeginSetServiceProperties, this.EndSetServiceProperties, properties, requestOptions, operationContext, cancellationToken); - } -#endif - - private RESTCommand GetServicePropertiesImpl(TableRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequestDelegate = TableHttpWebRequestFactory.GetServiceProperties; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.RetrieveResponseStream = true; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - retCmd.PostProcessResponse = (cmd, resp, ctx) => TableHttpWebResponseParsers.ReadServiceProperties(cmd.ResponseStream); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, TableRequestOptions requestOptions) - { - MultiBufferMemoryStream str = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(str); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - str.Seek(0, SeekOrigin.Begin); - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.SendStream = str; - retCmd.BuildRequestDelegate = TableHttpWebRequestFactory.SetServiceProperties; - retCmd.RecoveryAction = RecoveryActions.RewindStream; - retCmd.SignRequest = this.AuthenticationHandler.SignRequest; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - -#if !WINDOWS_PHONE - /// - /// Creates a new object for performing operations against the Table service. - /// - /// A service context to use for performing operations against the Table service. - [SuppressMessage( - "Microsoft.Design", - "CA1024:UsePropertiesWhereAppropriate", - Justification = "This method creates a new object each time.")] - public TableServiceContext GetTableServiceContext() - { - return new TableServiceContext(this); - } -#endif - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceContext.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceContext.cs deleted file mode 100644 index cea856fbeb561..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceContext.cs +++ /dev/null @@ -1,424 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Data.Services.Client; - using System.Globalization; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a object for use with the Windows Azure Table service. - /// - /// The class does not support concurrent queries or requests. - public class TableServiceContext : DataServiceContext, IDisposable - { - private IAuthenticationHandler authenticationHandler; - - /// - /// Initializes a new instance of the class. - /// - public TableServiceContext(CloudTableClient client) - : base(client.BaseUri) - { - CommonUtility.AssertNotNull("client", client); - - if (client.BaseUri == null) - { - throw new ArgumentNullException("client"); - } - - if (!client.BaseUri.IsAbsoluteUri) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, SR.RelativeAddressNotPermitted, client.BaseUri.ToString()); - - throw new ArgumentException(errorMessage, "client"); - } - - this.SendingRequest += this.TableServiceContext_SendingRequest; - - this.IgnoreMissingProperties = true; - this.MergeOption = MergeOption.PreserveChanges; - this.ServiceClient = client; - } - - #region Cancellation Support - internal void InternalCancel() - { - lock (this.cancellationLock) - { - this.cancellationRequested = true; - if (this.currentRequest != null) - { - this.currentRequest.Abort(); - } - } - } - - internal void ResetCancellation() - { - lock (this.cancellationLock) - { - this.cancellationRequested = false; - this.currentRequest = null; - } - } - - private object cancellationLock = new object(); - - private bool cancellationRequested = false; - - private HttpWebRequest currentRequest = null; - #endregion - - #region Signing + Execution - - // Action to hook up response header parsing - private Action sendingSignedRequestAction; - - internal Action SendingSignedRequestAction - { - get { return this.sendingSignedRequestAction; } - set { this.sendingSignedRequestAction = value; } - } - - // Only one concurrent operation per context is supported. - private Semaphore contextSemaphore = new Semaphore(1, 1); - - internal Semaphore ContextSemaphore - { - get { return this.contextSemaphore; } - } - - /// - /// Callback on DataContext object sending request. - /// - /// The sender. - /// The instance containing the event data. - private void TableServiceContext_SendingRequest(object sender, SendingRequestEventArgs e) - { - HttpWebRequest request = e.Request as HttpWebRequest; - - // Check timeout - int timeoutDex = request.RequestUri.Query.LastIndexOf("&timeout=", System.StringComparison.Ordinal); - if (timeoutDex > 0) - { - timeoutDex += 9; // Magic number -> length of "&timeout=" - int endDex = request.RequestUri.Query.IndexOf('&', timeoutDex); - string timeoutString = endDex > 0 - ? request.RequestUri.Query.Substring(timeoutDex, endDex - timeoutDex) - : request.RequestUri.Query.Substring(timeoutDex); - - int result = -1; - if (int.TryParse(timeoutString, out result) && result > 0) - { - request.Timeout = result * 1000; // Convert to ms - } - } - - // Sign request - if (this.ServiceClient.Credentials.IsSharedKey) - { - this.AuthenticationHandler.SignRequest(request, null /* operationContext */); - } - else if (this.ServiceClient.Credentials.IsSAS) - { - Uri transformedUri = this.ServiceClient.Credentials.TransformUri(request.RequestUri); - - // Recreate the request - HttpWebRequest newRequest = WebRequest.Create(transformedUri) as HttpWebRequest; - TableUtilities.CopyRequestData(newRequest, request); - e.Request = newRequest; - request = newRequest; - } - - lock (this.cancellationLock) - { - if (this.cancellationRequested) - { - throw new OperationCanceledException(SR.OperationCanceled); - } - - this.currentRequest = request; - } - - // SAS will be handled directly by the queries themselves prior to transformation - request.Headers.Add( - Constants.HeaderConstants.StorageVersionHeader, - Constants.HeaderConstants.TargetStorageVersion); - - CommonUtility.ApplyRequestOptimizations(request, -1); - - if (this.sendingSignedRequestAction != null) - { - this.sendingSignedRequestAction(request); - } - } - #endregion - - /// - /// Gets the object that represents the Table service. - /// - /// A client object that specifies the Table service endpoint. - public CloudTableClient ServiceClient { get; private set; } - - /// - /// Gets the authentication handler used to sign HTTP requests. - /// - /// The authentication handler. - private IAuthenticationHandler AuthenticationHandler - { - get - { - if (this.authenticationHandler == null) - { - if (this.ServiceClient.Credentials.IsSharedKey) - { - // Always use Shared Key Lite because Data Services adds a Content-Type HTTP header to requests - // that is not available during signing - this.authenticationHandler = new SharedKeyAuthenticationHandler( - SharedKeyLiteTableCanonicalizer.Instance, - this.ServiceClient.Credentials, - this.ServiceClient.Credentials.AccountName); - } - else - { - this.authenticationHandler = new NoOpAuthenticationHandler(); - } - } - - return this.authenticationHandler; - } - } - - /// - /// Saves changes, using the retry policy specified for the service context. - /// - /// A that represents the result of the operation. - [DoesServiceRequest] - public DataServiceResponse SaveChangesWithRetries() - { - return this.SaveChangesWithRetries(this.SaveChangesDefaultOptions); - } - - /// - /// Saves changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// - /// - /// A that represents the result of the operation. - [DoesServiceRequest] - public DataServiceResponse SaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - TableCommand cmd = this.GenerateSaveChangesCommand(options, requestOptions); - return TableExecutor.ExecuteSync(cmd, requestOptions.RetryPolicy, operationContext); - } - - /// - /// Begins an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSaveChangesWithRetries(AsyncCallback callback, object state) - { - return this.BeginSaveChangesWithRetries(this.SaveChangesDefaultOptions, callback, state); - } - - /// - /// Begins an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, AsyncCallback callback, object state) - { - return this.BeginSaveChangesWithRetries(options, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginSaveChangesWithRetries(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - TableCommand cmd = this.GenerateSaveChangesCommand(options, requestOptions); - return TableExecutor.BeginExecuteAsync(cmd, requestOptions.RetryPolicy, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to save changes. - /// - /// An that references the pending asynchronous operation. - /// A that represents the result of the operation. - public DataServiceResponse EndSaveChangesWithRetries(IAsyncResult asyncResult) - { - return TableExecutor.EndExecuteAsync(asyncResult); - } - -#if TASK - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync() - { - return this.SaveChangesWithRetriesAsync(CancellationToken.None); - } - - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync(CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, cancellationToken); - } - - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync(SaveChangesOptions options) - { - return this.SaveChangesWithRetriesAsync(options, CancellationToken.None); - } - - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync(SaveChangesOptions options, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, options, cancellationToken); - } - - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.SaveChangesWithRetriesAsync(options, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a object that performs an asynchronous operation to save changes, using the retry policy specified for the service context. - /// - /// Additional options for saving changes. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task SaveChangesWithRetriesAsync(SaveChangesOptions options, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginSaveChangesWithRetries, this.EndSaveChangesWithRetries, options, requestOptions, operationContext, cancellationToken); - } -#endif - - internal TableCommand GenerateSaveChangesCommand(SaveChangesOptions options, TableRequestOptions requestOptions) - { - TableCommand cmd = new TableCommand(); - - if (requestOptions.ServerTimeout.HasValue) - { - this.Timeout = (int)requestOptions.ServerTimeout.Value.TotalSeconds; - } - - cmd.ExecuteFunc = () => this.SaveChanges(options); - cmd.Begin = (callback, state) => this.BeginSaveChanges(options, callback, state); - cmd.End = this.EndSaveChanges; - cmd.ParseResponse = this.ParseDataServiceResponse; - cmd.ApplyRequestOptions(requestOptions); - cmd.Context = this; - - return cmd; - } - - private DataServiceResponse ParseDataServiceResponse(DataServiceResponse resp, RequestResult reqResult, TableCommand cmd) - { - if (reqResult.Exception != null) - { - throw reqResult.Exception; - } - - return resp; - } - - /// - /// Releases all resources used by the TableServiceContext. - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases the unmanaged resources used by the TableServiceContext and optionally releases the managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (this.contextSemaphore != null) - { - this.contextSemaphore.Dispose(); - this.contextSemaphore = null; - } - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceEntity.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceEntity.cs deleted file mode 100644 index 7cf97a5f7dce0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceEntity.cs +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - using System; - using System.Data.Services.Common; - using System.Diagnostics.CodeAnalysis; - - /// - /// Represents an entity in the Windows Azure Table service. - /// - [DataServiceKey("PartitionKey", "RowKey")] - public abstract class TableServiceEntity - { - /// - /// Initializes a new instance of the class. - /// - /// The partition key. - /// The row key. - [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "Reviewed.")] - protected TableServiceEntity(string partitionKey, string rowKey) - { - this.PartitionKey = partitionKey; - this.RowKey = rowKey; - } - - /// - /// Initializes a new instance of the class. - /// - protected TableServiceEntity() - { - } - - /// - /// Gets or sets the timestamp for the entity. - /// - /// The entity's timestamp. - public DateTime Timestamp { get; set; } - - /// - /// Gets or sets the partition key of a table entity. - /// - /// The partition key. - public virtual string PartitionKey { get; set; } - - /// - /// Gets or sets the row key of a table entity. - /// - /// The row key. - public virtual string RowKey { get; set; } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceExtensions.cs deleted file mode 100644 index f7cea5d489a03..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - using System.Data.Services.Client; - using System.Linq; - - /// - /// Provides a set of extensions for the Table service. - /// - public static class TableServiceExtensions - { - /// - /// Converts the query into a object that supports - /// additional operations like retries. - /// - /// The type of the element. - /// The query. - /// A object that represents the runtime context of the Table service. - /// The converted query. - public static TableServiceQuery AsTableServiceQuery(this IQueryable query, TableServiceContext context) - { - return new TableServiceQuery(query as DataServiceQuery, context); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceQuery.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceQuery.cs deleted file mode 100644 index 2f3c34335177f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/DataServices/TableServiceQuery.cs +++ /dev/null @@ -1,310 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections; - using System.Collections.Generic; - using System.Data.Services.Client; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Linq; - using System.Linq.Expressions; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// A class for constructing a query against the Table service. - /// - /// The type of the element. - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Reviewed")] - public class TableServiceQuery : IQueryable - { - /// - /// Initializes a new instance of the class. - /// - /// An object that implements . - /// A object. - public TableServiceQuery(IQueryable query, TableServiceContext context) - { - this.Query = query as DataServiceQuery; - this.Context = context; - this.IgnoreResourceNotFoundException = false; - } - - /// - /// Gets the table service context. - /// - /// - /// An object of type . - /// - public TableServiceContext Context { get; private set; } - - /// - /// Stores the wrapped . - /// - internal DataServiceQuery Query { get; set; } - - internal bool IgnoreResourceNotFoundException { get; set; } - - /// - /// Gets the type of the element(s) that are returned when the expression tree associated with this - /// instance of is executed. - /// - /// - /// A that represents the type of the element(s) that are returned when the expression tree associated with this object is executed. - /// - public Type ElementType - { - get { return this.Query.ElementType; } - } - - /// - /// Gets the expression tree that is associated with the instance of . - /// - /// - /// The that is associated with this instance of . - /// - public Expression Expression - { - get { return this.Query.Expression; } - } - - /// - /// Gets the query provider that is associated with this data source. - /// - /// - /// The that is associated with this data source. - /// - public IQueryProvider Provider - { - get { return this.Query.Provider; } - } - - /// - /// Expands the specified path. - /// - /// The path to expand. - /// A new query with the expanded path. - public TableServiceQuery Expand(string path) - { - return new TableServiceQuery(this.Query.Expand(path), this.Context); - } - - /// - /// Returns an enumerator that iterates through the collection. - /// - /// - /// A that can be used to iterate through the collection. - /// - public IEnumerator GetEnumerator() - { - return this.Execute(null /* RequestOptions */, null /* OperationContext */).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator() as IEnumerator; - } - - /// - /// Executes the request with any specified options. - /// - /// An object of type . - /// An object for tracking the current operation. - /// An enumerable collection, specialized for type TElement, of the results of executing the query. - [DoesServiceRequest] - public IEnumerable Execute(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.Context.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - long takeCount = TableUtilities.GetQueryTakeCount(this.Query, long.MaxValue); - return CommonUtility.LazyEnumerable( - (continuationToken) => this.ExecuteSegmentedCore((TableContinuationToken)continuationToken, requestOptions, operationContext), - takeCount); - } - - /// - /// Executes a segmented query against the Table service. - /// - /// The continuation token. - /// The request options. - /// An object for tracking the current operation. - /// A result segment containing objects of type . - [DoesServiceRequest] - public TableQuerySegment ExecuteSegmented(TableContinuationToken continuationToken, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.Context.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - return new TableQuerySegment(this.ExecuteSegmentedCore(continuationToken, requestOptions, operationContext)); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteSegmented(TableContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginExecuteSegmented(currentToken, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteSegmented(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.Context.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - TableCommand, IEnumerable> cmd = this.GenerateExecuteCommand( - currentToken, requestOptions); - return TableExecutor.BeginExecuteAsync(cmd, requestOptions.RetryPolicy, operationContext, callback, state); - } - - /// - /// Ends an asynchronous operation to execute a query and return the results as a result segment. - /// - /// The reference to the pending asynchronous request to finish. - /// A result segment containing objects of type . - public TableQuerySegment EndExecuteSegmented(IAsyncResult asyncResult) - { - return new TableQuerySegment(TableExecutor.EndExecuteAsync, IEnumerable>(asyncResult)); - } - -#if TASK - /// - /// Returns a task that performs an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken) - { - return this.ExecuteSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteSegmented, this.EndExecuteSegmented, currentToken, cancellationToken); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteSegmentedAsync(currentToken, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Returns a task that performs an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A to observe while waiting for a task to complete. - /// A object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteSegmented, this.EndExecuteSegmented, currentToken, requestOptions, operationContext, cancellationToken); - } -#endif - - internal ResultSegment ExecuteSegmentedCore(TableContinuationToken continuationToken, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableCommand, IEnumerable> cmd = this.GenerateExecuteCommand(continuationToken, requestOptions); - - return TableExecutor.ExecuteSync(cmd, requestOptions.RetryPolicy, operationContext); - } - - private TableCommand, IEnumerable> GenerateExecuteCommand(TableContinuationToken continuationToken, TableRequestOptions requestOptions) - { - DataServiceQuery localQuery = this.Query; - - // Continuation - localQuery = TableUtilities.ApplyContinuationToQuery(continuationToken, localQuery); - - if (requestOptions.ServerTimeout.HasValue) - { - localQuery = localQuery.AddQueryOption("timeout", Convert.ToString(requestOptions.ServerTimeout.Value.TotalSeconds, CultureInfo.InvariantCulture)); - } - - TableCommand, IEnumerable> cmd = new TableCommand, IEnumerable>(); - - cmd.ExecuteFunc = localQuery.Execute; - cmd.Begin = (callback, state) => localQuery.BeginExecute(callback, state); - cmd.End = localQuery.EndExecute; - cmd.ParseResponse = this.ParseTableQueryResponse; - cmd.ApplyRequestOptions(requestOptions); - cmd.Context = this.Context; - return cmd; - } - - private ResultSegment ParseTableQueryResponse(IEnumerable dataServiceQueryResponse, RequestResult reqResult, TableCommand, IEnumerable> cmd) - { - if (reqResult.Exception != null) - { - DataServiceClientException dsce = TableUtilities.FindInnerExceptionOfType(reqResult.Exception); - - if (this.IgnoreResourceNotFoundException && dsce != null && (HttpStatusCode)dsce.StatusCode == HttpStatusCode.NotFound) - { - return new ResultSegment(new List()); - } - - throw reqResult.Exception; - } - - QueryOperationResponse response = dataServiceQueryResponse as QueryOperationResponse; - - ResultSegment retSeg = new ResultSegment(dataServiceQueryResponse.ToList()); - - // Get continuation token from response - retSeg.ContinuationToken = TableUtilities.ContinuationFromResponse(response); - - return retSeg; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/IgnorePropertyAttribute.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/IgnorePropertyAttribute.cs deleted file mode 100644 index 9a6e2dd453132..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/IgnorePropertyAttribute.cs +++ /dev/null @@ -1,29 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - - /// - /// Represents a custom attribute that can be used to ignore entity properties during serialization/de-serialization. - /// - [AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple = false)] - public sealed class IgnorePropertyAttribute : Attribute - { - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpResponseAdapterMessage.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpResponseAdapterMessage.cs deleted file mode 100644 index 31b6b696fa3c8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpResponseAdapterMessage.cs +++ /dev/null @@ -1,98 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using System; - using System.Collections.Generic; - using System.IO; - using System.Net; - using System.Threading.Tasks; - - internal class HttpResponseAdapterMessage : IODataResponseMessage - { - private HttpWebResponse resp = null; - private Stream str = null; - - public HttpResponseAdapterMessage(HttpWebResponse resp, Stream str) - { - this.resp = resp; - this.str = str; - } - - public Task GetStreamAsync() - { - return Task.Factory.StartNew(() => this.str); - } - - public string GetHeader(string headerName) - { - if (headerName == "Content-Type") - { - return this.resp.ContentType; - } - -#if !WINDOWS_PHONE - if (headerName == "Content-Encoding") - { - return this.resp.ContentEncoding; - } -#endif - - return this.resp.Headers[headerName]; - } - - public Stream GetStream() - { - return this.str; - } - - public IEnumerable> Headers - { - get - { - List> retHeaders = new List>(); - - foreach (string key in this.resp.Headers.AllKeys) - { - retHeaders.Add(new KeyValuePair(key, this.resp.Headers[key])); - } - - return retHeaders; - } - } - - public void SetHeader(string headerName, string headerValue) - { - throw new NotImplementedException(); - } - - public int StatusCode - { - get - { - return (int)this.resp.StatusCode; - } - - set - { - throw new NotSupportedException(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpWebRequestAdapterMessage.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpWebRequestAdapterMessage.cs deleted file mode 100644 index fbd7d2b460b9d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/HttpWebRequestAdapterMessage.cs +++ /dev/null @@ -1,122 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - - internal class HttpWebRequestAdapterMessage : IODataRequestMessage, IDisposable - { - public HttpWebRequestAdapterMessage(HttpWebRequest msg, IBufferManager buffManager) - { - this.msg = msg; - this.outStr = new MultiBufferMemoryStream(buffManager); - } - - private HttpWebRequest msg = null; - - private MultiBufferMemoryStream outStr = null; - - public HttpWebRequest GetPopulatedMessage() - { - this.outStr.Seek(0, SeekOrigin.Begin); - this.msg.ContentLength = this.outStr.Length; - return this.msg; - } - - public string GetHeader(string headerName) - { - if (headerName == "Content-Type") - { - return this.msg.ContentType; - } - - return this.msg.Headers[headerName]; - } - - public Stream GetStream() - { - return this.outStr; - } - - public System.Collections.Generic.IEnumerable> Headers - { - get - { - List> retHeaders = new List>(); - - foreach (string key in this.msg.Headers.AllKeys) - { - retHeaders.Add(new KeyValuePair(key, this.msg.Headers[key])); - } - - return retHeaders; - } - } - - public string Method - { - get - { - return this.msg.Method; - } - - set - { - this.msg.Method = value; - } - } - - public void SetHeader(string headerName, string headerValue) - { - if (headerName == "Content-Type") - { - this.msg.ContentType = headerValue; - } - else - { - this.msg.Headers[headerName] = headerValue; - } - } - - public Uri Url - { - get - { - return this.msg.RequestUri; - } - - set - { - throw new NotSupportedException(); - } - } - - [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Justification = "The memory stream is used after this adapter message is disposed", MessageId = "outStr")] - public void Dispose() - { - this.msg = null; - this.outStr = null; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebRequestFactory.cs deleted file mode 100644 index 3f3f8700b2745..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebRequestFactory.cs +++ /dev/null @@ -1,104 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.IO; - using System.Net; - - /// - /// A factory class for constructing a web request to manage tables in the Table service. - /// - public static class TableHttpWebRequestFactory - { - /// - /// Creates a web request to get the properties of the Table service. - /// - /// The absolute URI to the Table service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to get the Table service properties. - /// - public static HttpWebRequest GetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.GetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Creates a web request to set the properties of the Table service. - /// - /// The absolute URI to the Table service. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval, in seconds. - /// An object for tracking the current operation. - /// - /// A web request to set the Table service properties. - /// - public static HttpWebRequest SetServiceProperties(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.SetServiceProperties(uri, builder, timeout, operationContext); - } - - /// - /// Writes Table service properties to a stream, formatted in XML. - /// - /// The service properties to format and write to the stream. - /// The stream to which the formatted properties are to be written. - public static void WriteServiceProperties(ServiceProperties properties, Stream outputStream) - { - CommonUtility.AssertNotNull("properties", properties); - - properties.WriteServiceProperties(outputStream); - } - - /// - /// Constructs a web request to return the ACL for a table. - /// - /// The absolute URI to the table. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest GetAcl(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.GetAcl(uri, builder, timeout, operationContext); - } - - /// - /// Constructs a web request to set the ACL for a table. - /// - /// The absolute URI to the table. - /// An object of type , containing additional parameters to add to the URI query string. - /// The server timeout interval. - /// An object for tracking the current operation. - /// - /// A web request to use to perform the operation. - /// - public static HttpWebRequest SetAcl(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext operationContext) - { - return HttpWebRequestFactory.SetAcl(uri, builder, timeout, operationContext); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebResponseParsers.cs deleted file mode 100644 index f39ea86195976..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableHttpWebResponseParsers.cs +++ /dev/null @@ -1,62 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System.IO; - using System.Net; - - /// - /// Provides a set of methods for parsing a response stream from the Table service. - /// - public static class TableHttpWebResponseParsers - { - /// - /// Gets the request ID from the response. - /// - /// The web response. - /// A unique value associated with the request. - public static string GetRequestId(HttpWebResponse response) - { - return Response.GetRequestId(response); - } - - /// - /// Reads service properties from a stream. - /// - /// The stream from which to read the service properties. - /// The service properties stored in the stream. - public static ServiceProperties ReadServiceProperties(Stream inputStream) - { - return HttpResponseParsers.ReadServiceProperties(inputStream); - } - - /// - /// Reads the share access policies from a stream in XML. - /// - /// The stream of XML policies. - /// The permissions object to which the policies are to be written. - public static void ReadSharedAccessIdentifiers(Stream inputStream, TablePermissions permissions) - { - CommonUtility.AssertNotNull("permissions", permissions); - - HttpResponseParsers.ReadSharedAccessIdentifiers(permissions.SharedAccessPolicies, new TableAccessPolicyResponse(inputStream)); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpRequestFactory.cs deleted file mode 100644 index 855ad6aea497c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpRequestFactory.cs +++ /dev/null @@ -1,202 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - - internal static class TableOperationHttpWebRequestFactory - { - internal static HttpWebRequest BuildRequestCore(Uri uri, UriQueryBuilder builder, string method, int? timeout, OperationContext ctx) - { - HttpWebRequest msg = HttpWebRequestFactory.CreateWebRequest(method, uri, timeout, builder, ctx); - msg.Accept = "application/atom+xml,application/xml"; - msg.Headers.Add("Accept-Charset", "UTF-8"); - msg.Headers.Add("MaxDataServiceVersion", "2.0;NetFx"); - - return msg; - } - - internal static HttpWebRequest BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int? timeout, OperationContext ctx) - { - HttpWebRequest msg = BuildRequestCore(uri, builder, "GET", timeout, ctx); - - return msg; - } - - internal static Tuple BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, TableOperation operation, OperationContext ctx) - { - HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, ctx); - - if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) - { - // post tunnelling - msg.Headers.Add("X-HTTP-Method", "MERGE"); - } - - // etag - if (operation.OperationType == TableOperationType.Delete || - operation.OperationType == TableOperationType.Replace || - operation.OperationType == TableOperationType.Merge) - { - if (operation.Entity.ETag != null) - { - msg.Headers.Add("If-Match", operation.Entity.ETag); - } - } - - if (operation.OperationType == TableOperationType.Insert || - operation.OperationType == TableOperationType.Merge || - operation.OperationType == TableOperationType.InsertOrMerge || - operation.OperationType == TableOperationType.InsertOrReplace || - operation.OperationType == TableOperationType.Replace) - { - // create the writer, indent for readability of the examples. - ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() - { - CheckCharacters = false, // sets this flag on the XmlWriter for ATOM - Version = ODataVersion.V2 // set the Odata version to use when writing the entry - }; - - HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); - ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); - ODataWriter writer = odataWriter.CreateODataEntryWriter(); - WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer); - - return new Tuple(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream()); - } - - return new Tuple(msg, null); - } - - internal static Tuple BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, Uri baseUri, string tableName, TableBatchOperation batch, OperationContext ctx) - { - HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToUri(uri, "$batch"), builder, "POST", timeout, ctx); - - // create the writer, indent for readability of the examples. - ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() - { - CheckCharacters = false, // sets this flag on the XmlWriter for ATOM - Version = ODataVersion.V2 // set the Odata version to use when writing the entry - }; - - HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); - - // Start Batch - ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); - ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter(); - batchWriter.WriteStartBatch(); - - bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; - - // Query operations should not be inside changeset in payload - if (!isQuery) - { - // Start Operation - batchWriter.WriteStartChangeset(); - batchWriter.Flush(); - } - - foreach (TableOperation operation in batch) - { - string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod; - - ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(baseUri, tableName)); - - // etag - if (operation.OperationType == TableOperationType.Delete || - operation.OperationType == TableOperationType.Replace || - operation.OperationType == TableOperationType.Merge) - { - mimePartMsg.SetHeader("If-Match", operation.Entity.ETag); - } - - if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) - { - using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings)) - { - // Write entity - ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter(); - WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter); - } - } - } - - if (!isQuery) - { - // End Operation - batchWriter.WriteEndChangeset(); - } - - // End Batch - batchWriter.WriteEndBatch(); - batchWriter.Flush(); - - return new Tuple(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream()); - } - - private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer) - { - ODataEntry entry = new ODataEntry() - { - Properties = GetPropertiesWithKeys(entity, ctx) - }; - - if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve) - { - entry.ETag = entity.ETag; - } - - writer.WriteStart(entry); - writer.WriteEnd(); - writer.Flush(); - } - - #region TableEntity Serialization Helpers - - internal static List GetPropertiesFromDictionary(IDictionary properties) - { - return properties.Select(kvp => new ODataProperty() { Name = kvp.Key, Value = kvp.Value.PropertyAsObject }).ToList(); - } - - internal static List GetPropertiesWithKeys(ITableEntity entity, OperationContext operationContext) - { - List retProps = GetPropertiesFromDictionary(entity.WriteEntity(operationContext)); - - if (entity.PartitionKey != null) - { - retProps.Add(new ODataProperty() { Name = TableConstants.PartitionKey, Value = entity.PartitionKey }); - } - - if (entity.RowKey != null) - { - retProps.Add(new ODataProperty() { Name = TableConstants.RowKey, Value = entity.RowKey }); - } - - return retProps; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpResponseParsers.cs deleted file mode 100644 index bc3a0e55ff021..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableOperationHttpResponseParsers.cs +++ /dev/null @@ -1,426 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Net; - - internal class TableOperationHttpResponseParsers - { - internal static TableResult TableOperationPreProcess(TableResult result, TableOperation operation, HttpWebResponse resp, Exception ex, StorageCommandBase cmd) - { - result.HttpStatusCode = (int)resp.StatusCode; - - if (operation.OperationType == TableOperationType.Retrieve) - { - if (resp.StatusCode != HttpStatusCode.OK && resp.StatusCode != HttpStatusCode.NotFound) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - } - else - { - if (ex != null) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - else if (operation.OperationType == TableOperationType.Insert) - { - if (resp.StatusCode != HttpStatusCode.Created) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - } - else - { - if (resp.StatusCode != HttpStatusCode.NoContent) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - } - } - - string etag = HttpResponseParsers.GetETag(resp); - if (etag != null) - { - result.Etag = etag; - if (operation.Entity != null) - { - operation.Entity.ETag = result.Etag; - } - } - - return result; - } - - internal static TableResult TableOperationPostProcess(TableResult result, TableOperation operation, RESTCommand cmd, HttpWebResponse resp, OperationContext ctx) - { - if (operation.OperationType != TableOperationType.Retrieve && operation.OperationType != TableOperationType.Insert) - { - result.Etag = HttpResponseParsers.GetETag(resp); - operation.Entity.ETag = result.Etag; - } - else - { - // Parse entity - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - ReadOdataEntity(result, operation, new HttpResponseAdapterMessage(resp, cmd.ResponseStream), ctx, readerSettings); - } - - return result; - } - - internal static IList TableBatchOperationPostProcess(IList result, TableBatchOperation batch, RESTCommand> cmd, HttpWebResponse resp, OperationContext ctx) - { - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, cmd.ResponseStream), readerSettings)) - { - // create a reader - ODataBatchReader reader = responseReader.CreateODataBatchReader(); - - // Initial => changesetstart - if (reader.State == ODataBatchReaderState.Initial) - { - reader.Read(); - } - - if (reader.State == ODataBatchReaderState.ChangesetStart) - { - // ChangeSetStart => Operation - reader.Read(); - } - - int index = 0; - bool failError = false; - bool failUnexpected = false; - - while (reader.State == ODataBatchReaderState.Operation) - { - TableOperation currentOperation = batch[index]; - TableResult currentResult = new TableResult() { Result = currentOperation.Entity }; - result.Add(currentResult); - - ODataBatchOperationResponseMessage mimePartResponseMessage = reader.CreateOperationResponseMessage(); - currentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - - // Validate Status Code - if (currentOperation.OperationType == TableOperationType.Insert) - { - failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.Conflict; - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.Created; - } - else if (currentOperation.OperationType == TableOperationType.Retrieve) - { - if (mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound) - { - index++; - - // Operation => next - reader.Read(); - continue; - } - - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.OK; - } - else - { - failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound; - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; - } - - if (failError) - { - cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); - cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - - throw new StorageException( - cmd.CurrentResult, - cmd.CurrentResult.ExtendedErrorInformation != null ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : SR.ExtendedErrorUnavailable, - null) - { - IsRetryable = false - }; - } - - if (failUnexpected) - { - cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); - cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - - string indexString = Convert.ToString(index, CultureInfo.InvariantCulture); - - // Attempt to extract index of failing entity from extended error info - if (cmd.CurrentResult.ExtendedErrorInformation != null && - !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) - { - string tempIndex = TableRequest.ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); - if (!string.IsNullOrEmpty(tempIndex)) - { - indexString = tempIndex; - } - } - - throw new StorageException(cmd.CurrentResult, SR.UnexpectedResponseCodeForOperation + indexString, null) { IsRetryable = true }; - } - - // Update etag - if (!string.IsNullOrEmpty(mimePartResponseMessage.GetHeader("ETag"))) - { - currentResult.Etag = mimePartResponseMessage.GetHeader("ETag"); - - if (currentOperation.Entity != null) - { - currentOperation.Entity.ETag = currentResult.Etag; - } - } - - // Parse Entity if needed - if (currentOperation.OperationType == TableOperationType.Retrieve || currentOperation.OperationType == TableOperationType.Insert) - { - ReadOdataEntity(currentResult, currentOperation, mimePartResponseMessage, ctx, readerSettings); - } - - index++; - - // Operation => - reader.Read(); - } - } - - return result; - } - - internal static ResultSegment TableQueryPostProcessGeneric(Stream responseStream, Func, string, TElement> resolver, HttpWebResponse resp) - { - ResultSegment retSeg = new ResultSegment(new List()); - retSeg.ContinuationToken = ContinuationFromResponse(resp); - - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, responseStream), readerSettings)) - { - // create a reader - ODataReader reader = responseReader.CreateODataFeedReader(); - - // Start => FeedStart - if (reader.State == ODataReaderState.Start) - { - reader.Read(); - } - - // Feedstart - if (reader.State == ODataReaderState.FeedStart) - { - reader.Read(); - } - - while (reader.State == ODataReaderState.EntryStart) - { - // EntryStart => EntryEnd - reader.Read(); - - ODataEntry entry = (ODataEntry)reader.Item; - - retSeg.Results.Add(ReadAndResolve(entry, resolver)); - - // Entry End => ? - reader.Read(); - } - - DrainODataReader(reader); - } - - return retSeg; - } - - private static void DrainODataReader(ODataReader reader) - { - if (reader.State == ODataReaderState.FeedEnd) - { - reader.Read(); - } - - if (reader.State != ODataReaderState.Completed) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, SR.ODataReaderNotInCompletedState, reader.State)); - } - } - - /// - /// Gets the table continuation from response. - /// - /// The response. - /// The continuation. - internal static TableContinuationToken ContinuationFromResponse(HttpWebResponse response) - { - string nextPartitionKey = response.Headers[TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextPartitionKey]; - string nextRowKey = response.Headers[TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextRowKey]; - string nextTableName = response.Headers[TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextTableName]; - - nextPartitionKey = string.IsNullOrEmpty(nextPartitionKey) ? null : nextPartitionKey; - nextRowKey = string.IsNullOrEmpty(nextRowKey) ? null : nextRowKey; - nextTableName = string.IsNullOrEmpty(nextTableName) ? null : nextTableName; - - if (nextPartitionKey == null && nextRowKey == null && nextTableName == null) - { - return null; - } - - TableContinuationToken newContinuationToken = new TableContinuationToken() - { - NextPartitionKey = nextPartitionKey, - NextRowKey = nextRowKey, - NextTableName = nextTableName - }; - - return newContinuationToken; - } - - private static void ReadOdataEntity(TableResult result, TableOperation operation, IODataResponseMessage respMsg, OperationContext ctx, ODataMessageReaderSettings readerSettings) - { - using (ODataMessageReader messageReader = new ODataMessageReader(respMsg, readerSettings)) - { - // create a reader - ODataReader reader = messageReader.CreateODataEntryReader(); - - while (reader.Read()) - { - if (reader.State == ODataReaderState.EntryEnd) - { - ODataEntry entry = (ODataEntry)reader.Item; - - if (operation.OperationType == TableOperationType.Retrieve) - { - result.Result = ReadAndResolve(entry, operation.RetrieveResolver); - result.Etag = entry.ETag; - } - else - { - result.Etag = ReadAndUpdateTableEntity( - operation.Entity, - entry, - EntityReadFlags.Timestamp | EntityReadFlags.Etag, - ctx); - } - } - } - - DrainODataReader(reader); - } - } - - private static T ReadAndResolve(ODataEntry entry, Func, string, T> resolver) - { - string pk = null; - string rk = null; - DateTimeOffset ts = new DateTimeOffset(); - Dictionary properties = new Dictionary(); - - foreach (ODataProperty prop in entry.Properties) - { - string propName = prop.Name; - if (propName == TableConstants.PartitionKey) - { - pk = (string)prop.Value; - } - else if (propName == TableConstants.RowKey) - { - rk = (string)prop.Value; - } - else if (propName == TableConstants.Timestamp) - { - ts = new DateTimeOffset((DateTime)prop.Value); - } - else - { - properties.Add(propName, EntityProperty.CreateEntityPropertyFromObject(prop.Value)); - } - } - - return resolver(pk, rk, ts, properties, entry.ETag); - } - - // returns etag - internal static string ReadAndUpdateTableEntity(ITableEntity entity, ODataEntry entry, EntityReadFlags flags, OperationContext ctx) - { - if ((flags & EntityReadFlags.Etag) > 0) - { - entity.ETag = entry.ETag; - } - - Dictionary entityProperties = (flags & EntityReadFlags.Properties) > 0 ? new Dictionary() : null; - - if (flags > 0) - { - foreach (ODataProperty prop in entry.Properties) - { - if (prop.Name == TableConstants.PartitionKey) - { - if ((flags & EntityReadFlags.PartitionKey) == 0) - { - continue; - } - - entity.PartitionKey = (string)prop.Value; - } - else if (prop.Name == TableConstants.RowKey) - { - if ((flags & EntityReadFlags.RowKey) == 0) - { - continue; - } - - entity.RowKey = (string)prop.Value; - } - else if (prop.Name == TableConstants.Timestamp) - { - if ((flags & EntityReadFlags.Timestamp) == 0) - { - continue; - } - - entity.Timestamp = (DateTime)prop.Value; - } - else if ((flags & EntityReadFlags.Properties) > 0) - { - entityProperties.Add(prop.Name, EntityProperty.CreateEntityPropertyFromObject(prop.Value)); - } - } - - if ((flags & EntityReadFlags.Properties) > 0) - { - entity.ReadEntity(entityProperties, ctx); - } - } - - return entry.ETag; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableUtilities.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableUtilities.cs deleted file mode 100644 index 4788811a1de4e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/Protocol/TableUtilities.cs +++ /dev/null @@ -1,268 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ -#if WINDOWS_DESKTOP && ! WINDOWS_PHONE - using System; - using System.Data.Services.Client; - using System.IO; - using System.Linq.Expressions; - using System.Net; - using System.Text; - - internal static class TableUtilities - { - /// - /// Translates the data service client exception. - /// - /// The exception. - /// The request result. - /// - /// The translated exception. - /// - internal static StorageException TranslateDataServiceClientException(Exception e, RequestResult reqResult) - { - DataServiceClientException dsce = FindInnerExceptionOfType(e); - - if (dsce == null) - { - InvalidOperationException ioe = TableUtilities.FindInnerExceptionOfType(e); - - if (ioe != null && !(ioe is WebException) && ioe.Source == "System.Data.Services.Client" && ioe.Message.Contains("type is not compatible with the expected")) - { - return new StorageException(reqResult, e.Message, e) { IsRetryable = false }; - } - - return null; - } - else - { - reqResult.HttpStatusCode = dsce.StatusCode; - using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(dsce.Message))) - { - reqResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(stream); - } - - return new StorageException( - reqResult, - reqResult.ExtendedErrorInformation != null ? reqResult.ExtendedErrorInformation.ErrorCode : dsce.Message, - dsce); - } - } - - /// - /// Look for an inner exception of type T. - /// - /// The exception. - /// The found exception or null. - internal static T FindInnerExceptionOfType(Exception exception) where T : Exception - { - T dsce = null; - - while (exception != null) - { - dsce = exception as T; - - if (dsce != null) - { - break; - } - - exception = exception.InnerException; - } - - return dsce; - } - - /// - /// Applies the continuation to query. - /// - /// The continuation token. - /// The local query. - /// The modified query. - public static DataServiceQuery ApplyContinuationToQuery( - TableContinuationToken continuationToken, DataServiceQuery localQuery) - { - if (continuationToken != null) - { - if (continuationToken.NextPartitionKey != null) - { - localQuery = localQuery.AddQueryOption(TableConstants.TableServiceNextPartitionKey, continuationToken.NextPartitionKey); - } - - if (continuationToken.NextRowKey != null) - { - localQuery = localQuery.AddQueryOption(TableConstants.TableServiceNextRowKey, continuationToken.NextRowKey); - } - - if (continuationToken.NextTableName != null) - { - localQuery = localQuery.AddQueryOption(TableConstants.TableServiceNextTableName, continuationToken.NextTableName); - } - } - - return localQuery; - } - - /// - /// Gets the query take count. - /// - /// The type of the element. - /// The query. - /// The default value. - /// - /// The take count of the query, if any. - /// - public static long GetQueryTakeCount(DataServiceQuery query, long defaultValue) - { - MethodCallExpression expression = query.Expression as MethodCallExpression; - - if (expression != null && expression.Method.Name == "Take") - { - ConstantExpression argument = expression.Arguments[1] as ConstantExpression; - - if (argument != null) - { - return (long)((int)argument.Value); - } - } - - return defaultValue; - } - - /// - /// Gets the table continuation from response. - /// - /// The response. - /// The continuation. - public static TableContinuationToken ContinuationFromResponse(QueryOperationResponse response) - { - string nextPartitionKey; - string nextRowKey; - string nextTableName; - - response.Headers.TryGetValue( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextPartitionKey, - out nextPartitionKey); - response.Headers.TryGetValue( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextRowKey, - out nextRowKey); - response.Headers.TryGetValue( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextTableName, - out nextTableName); - - if (string.IsNullOrEmpty(nextPartitionKey) && string.IsNullOrEmpty(nextRowKey) && string.IsNullOrEmpty(nextTableName)) - { - return null; - } - - TableContinuationToken newContinuationToken = new TableContinuationToken() - { - NextPartitionKey = nextPartitionKey, - NextRowKey = nextRowKey, - NextTableName = nextTableName - }; - - return newContinuationToken; - } - - /// - /// Copies the headers and properties from a request into a different request. - /// - /// The request to copy into. - /// The request to copy from. - internal static void CopyRequestData(HttpWebRequest destinationRequest, HttpWebRequest sourceRequest) - { - // Copy the request properties - destinationRequest.AllowAutoRedirect = sourceRequest.AllowAutoRedirect; - destinationRequest.AllowWriteStreamBuffering = sourceRequest.AllowWriteStreamBuffering; - destinationRequest.AuthenticationLevel = sourceRequest.AuthenticationLevel; - destinationRequest.AutomaticDecompression = sourceRequest.AutomaticDecompression; - destinationRequest.CachePolicy = sourceRequest.CachePolicy; - destinationRequest.ClientCertificates = sourceRequest.ClientCertificates; - destinationRequest.ConnectionGroupName = sourceRequest.ConnectionGroupName; - destinationRequest.ContinueDelegate = sourceRequest.ContinueDelegate; - destinationRequest.CookieContainer = sourceRequest.CookieContainer; - destinationRequest.Credentials = sourceRequest.Credentials; - destinationRequest.ImpersonationLevel = sourceRequest.ImpersonationLevel; - destinationRequest.KeepAlive = sourceRequest.KeepAlive; - destinationRequest.MaximumAutomaticRedirections = sourceRequest.MaximumAutomaticRedirections; - destinationRequest.MaximumResponseHeadersLength = sourceRequest.MaximumResponseHeadersLength; - destinationRequest.MediaType = sourceRequest.MediaType; - destinationRequest.Method = sourceRequest.Method; - destinationRequest.Pipelined = sourceRequest.Pipelined; - destinationRequest.PreAuthenticate = sourceRequest.PreAuthenticate; - destinationRequest.ProtocolVersion = sourceRequest.ProtocolVersion; - destinationRequest.Proxy = sourceRequest.Proxy; - destinationRequest.ReadWriteTimeout = sourceRequest.ReadWriteTimeout; - destinationRequest.SendChunked = sourceRequest.SendChunked; - destinationRequest.Timeout = sourceRequest.Timeout; - destinationRequest.UnsafeAuthenticatedConnectionSharing = sourceRequest.UnsafeAuthenticatedConnectionSharing; - destinationRequest.UseDefaultCredentials = sourceRequest.UseDefaultCredentials; - - // Copy the headers. - // Some headers can't be copied over. We check for these headers. - foreach (string headerName in sourceRequest.Headers) - { - switch (headerName) - { - case "Accept": - destinationRequest.Accept = sourceRequest.Accept; - break; - - case "Connection": - destinationRequest.Connection = sourceRequest.Connection; - break; - - case "Content-Length": - destinationRequest.ContentLength = sourceRequest.ContentLength; - break; - - case "Content-Type": - destinationRequest.ContentType = sourceRequest.ContentType; - break; - - case "Expect": - destinationRequest.Expect = sourceRequest.Expect; - break; - - case "If-Modified-Since": - destinationRequest.IfModifiedSince = sourceRequest.IfModifiedSince; - break; - - case "Referer": - destinationRequest.Referer = sourceRequest.Referer; - break; - - case "Transfer-Encoding": - destinationRequest.TransferEncoding = sourceRequest.TransferEncoding; - break; - - case "User-Agent": - destinationRequest.UserAgent = sourceRequest.UserAgent; - break; - - default: - destinationRequest.Headers.Add(headerName, sourceRequest.Headers[headerName]); - break; - } - } - } - } -#endif -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableBatchOperation.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableBatchOperation.cs deleted file mode 100644 index 2b1fdbee31a7a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableBatchOperation.cs +++ /dev/null @@ -1,137 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - - /// - /// Represents a batch operation on a table. - /// - [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Back compatibility.")] - public sealed partial class TableBatchOperation : IList - { - #region Factories - /// - /// Inserts a into the batch that retrieves an entity based on its row key and partition key. The entity will be deserialized into the specified class type which extends . - /// - /// The class of type for the entity to retrieve. - /// A string containing the partition key of the entity to retrieve. - /// A string containing the row key of the entity to retrieve. - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Reviewed.")] - public void Retrieve(string partitionKey, string rowKey) where TElement : ITableEntity - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowKey); - - // Add the table operation. - this.Add(new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowKey, RetrieveResolver = (pk, rk, ts, prop, etag) => EntityUtilities.ResolveEntityByType(pk, rk, ts, prop, etag) }); - } - - /// - /// Adds a table operation to retrieve an entity of the specified class type with the specified partition key and row key to the batch operation. - /// - /// The return type which the specified will resolve the given entity to. - /// A string containing the partition key of the entity to retrieve. - /// A string containing the row key of the entity to retrieve. - /// The implementation to project the entity to retrieve as a particular type in the result. - public void Retrieve(string partitionKey, string rowKey, EntityResolver resolver) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowKey); - - // Add the table operation. - this.Add(new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowKey, RetrieveResolver = (pk, rk, ts, prop, etag) => resolver(pk, rk, ts, prop, etag) }); - } - - #endregion - -#if SYNC - [DoesServiceRequest] - internal IList Execute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - if (this.operations.Count == 0) - { - throw new InvalidOperationException(SR.EmptyBatchOperation); - } - - return Executor.ExecuteSync(BatchImpl(this, client, tableName, modifiedOptions), modifiedOptions.RetryPolicy, operationContext); - } -#endif - - [DoesServiceRequest] - internal ICancellableAsyncResult BeginExecute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - if (this.operations.Count == 0) - { - throw new InvalidOperationException(SR.EmptyBatchOperation); - } - - return Executor.BeginExecuteAsync( - BatchImpl(this, client, tableName, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - internal static IList EndExecute(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - - private static RESTCommand> BatchImpl(TableBatchOperation batch, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand> batchCmd = new RESTCommand>(client.Credentials, client.BaseUri); - batchCmd.ApplyRequestOptions(requestOptions); - - List results = new List(); - - batchCmd.RetrieveResponseStream = true; - batchCmd.SignRequest = client.AuthenticationHandler.SignRequest; - batchCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => - { - Tuple res = TableOperationHttpWebRequestFactory.BuildRequestForTableBatchOperation(uri, builder, client.BufferManager, timeout, client.BaseUri, tableName, batch, ctx); - batchCmd.SendStream = res.Item2; - return res.Item1; - }; - - batchCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp != null ? resp.StatusCode : HttpStatusCode.Unused, results, cmd, ex); - batchCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableBatchOperationPostProcess(results, batch, cmd, resp, ctx); - batchCmd.RecoveryAction = (cmd, ex, ctx) => results.Clear(); - - return batchCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableOperation.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableOperation.cs deleted file mode 100644 index 0ecb129ebe693..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableOperation.cs +++ /dev/null @@ -1,292 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net; - - /// - /// Represents a single table operation. - /// - public sealed partial class TableOperation - { - /// - /// Creates a new table operation that replaces the contents of - /// the given entity in a table. - /// - /// The class of type for the entity to retrieve. - /// A string containing the partition key of the entity to retrieve. - /// A string containing the row key of the entity to retrieve. - /// The object. - [SuppressMessage("Microsoft.Design", - "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Reviewed")] - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "rowkey", - Justification = "Reviewed : towkey is acceptable.")] - public static TableOperation Retrieve(string partitionKey, string rowkey) - where TElement : ITableEntity - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Create and return the table operation. - return new TableOperation(null /* entity */, TableOperationType.Retrieve) - { - RetrievePartitionKey = partitionKey, - RetrieveRowKey = rowkey, - RetrieveResolver = - (pk, rk, ts, prop, etag) => EntityUtilities.ResolveEntityByType( - pk, - rk, - ts, - prop, - etag) - }; - } - - /// - /// Creates a new table operation that replaces the contents of - /// the given entity in a table. - /// - /// The return type which the specified will resolve the given entity to. - /// A string containing the partition key of the entity to retrieve. - /// A string containing the row key of the entity to retrieve. - /// The implementation to project the entity to retrieve as a particular type in the result. - /// The object. - [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "rowkey", Justification = "Reviewed : rowkey is acceptable.")] - public static TableOperation Retrieve(string partitionKey, string rowkey, EntityResolver resolver) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Create and return the table operation. - return new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey, RetrieveResolver = (pk, rk, ts, prop, etag) => resolver(pk, rk, ts, prop, etag) }; - } - -#if SYNC - internal TableResult Execute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - return Executor.ExecuteSync(this.GenerateCMDForOperation(client, tableName, modifiedOptions), modifiedOptions.RetryPolicy, operationContext); - } -#endif - - [DoesServiceRequest] - internal ICancellableAsyncResult BeginExecute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - return Executor.BeginExecuteAsync( - this.GenerateCMDForOperation(client, tableName, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - internal static TableResult EndExecute(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync(asyncResult); - } - - internal RESTCommand GenerateCMDForOperation(CloudTableClient client, string tableName, TableRequestOptions modifiedOptions) - { - if (this.OperationType == TableOperationType.Insert || - this.OperationType == TableOperationType.InsertOrMerge || - this.OperationType == TableOperationType.InsertOrReplace) - { - if (!this.isTableEntity && this.OperationType != TableOperationType.Insert) - { - CommonUtility.AssertNotNull("Upserts require a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Upserts require a valid RowKey", this.Entity.RowKey); - } - - return InsertImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Delete) - { - if (!this.isTableEntity) - { - CommonUtility.AssertNotNullOrEmpty("Delete requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Delete requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Delete requires a valid RowKey", this.Entity.RowKey); - } - - return DeleteImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Merge) - { - CommonUtility.AssertNotNullOrEmpty("Merge requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Merge requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Merge requires a valid RowKey", this.Entity.RowKey); - - return MergeImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Replace) - { - CommonUtility.AssertNotNullOrEmpty("Replace requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Replace requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Replace requires a valid RowKey", this.Entity.RowKey); - - return ReplaceImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Retrieve) - { - return RetrieveImpl(this, client, tableName, modifiedOptions); - } - else - { - throw new NotSupportedException(); - } - } - - private static RESTCommand InsertImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand insertCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - insertCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - insertCmd.RetrieveResponseStream = true; - insertCmd.SignRequest = client.AuthenticationHandler.SignRequest; - insertCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => - { - Tuple res = TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx); - insertCmd.SendStream = res.Item2; - return res.Item1; - }; - - insertCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd); - - insertCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx); - - return insertCmd; - } - - private static RESTCommand DeleteImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand deleteCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - deleteCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - deleteCmd.RetrieveResponseStream = false; - deleteCmd.SignRequest = client.AuthenticationHandler.SignRequest; - deleteCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx).Item1; - deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd); - - return deleteCmd; - } - - private static RESTCommand MergeImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand mergeCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - mergeCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - mergeCmd.RetrieveResponseStream = false; - mergeCmd.SignRequest = client.AuthenticationHandler.SignRequest; - mergeCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => - { - Tuple res = TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx); - mergeCmd.SendStream = res.Item2; - return res.Item1; - }; - - mergeCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd); - - return mergeCmd; - } - - private static RESTCommand ReplaceImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand replaceCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - replaceCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - replaceCmd.RetrieveResponseStream = false; - replaceCmd.SignRequest = client.AuthenticationHandler.SignRequest; - replaceCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => - { - Tuple res = TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx); - replaceCmd.SendStream = res.Item2; - return res.Item1; - }; - - replaceCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd); - - return replaceCmd; - } - - private static RESTCommand RetrieveImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand retrieveCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - retrieveCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult(); - retrieveCmd.RetrieveResponseStream = true; - retrieveCmd.SignRequest = client.AuthenticationHandler.SignRequest; - retrieveCmd.BuildRequestDelegate = (uri, builder, timeout, ctx) => TableOperationHttpWebRequestFactory.BuildRequestForTableOperation(uri, builder, client.BufferManager, timeout, operation, ctx).Item1; - retrieveCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd); - retrieveCmd.PostProcessResponse = (cmd, resp, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return result; - } - - result = TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx); - return result; - }; - - return retrieveCmd; - } - - internal string HttpMethod - { - get - { - switch (this.OperationType) - { - case TableOperationType.Insert: - return "POST"; - case TableOperationType.Merge: - case TableOperationType.InsertOrMerge: - return "POST"; // Post tunneling for merge - case TableOperationType.Replace: - case TableOperationType.InsertOrReplace: - return "PUT"; - case TableOperationType.Delete: - return "DELETE"; - case TableOperationType.Retrieve: - return "GET"; - default: - throw new NotSupportedException(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQuery.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQuery.cs deleted file mode 100644 index d84b884e3c914..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQuery.cs +++ /dev/null @@ -1,563 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Queryable; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Linq.Expressions; - using System.Net; - using System.Threading; - using System.Threading.Tasks; - - /// - /// Represents a query against a Windows Azure table. - /// - /// A class which implements . - public partial class TableQuery : IQueryable - { - #region Private fields. - - private readonly Expression queryExpression; - - private readonly TableQueryProvider queryProvider; - - #endregion - - #region Ctors - - /// - /// Initializes a new instance of the class. - /// - public TableQuery() - { - // Instantiated by user, validate that Telement implements ITableEnity - if (typeof(TElement).GetInterface(typeof(ITableEntity).FullName, false) == null) - { - throw new NotSupportedException(SR.TableQueryTypeMustImplementITableEnitty); - } - - if (typeof(TElement).GetConstructor(System.Type.EmptyTypes) == null) - { - throw new NotSupportedException(SR.TableQueryTypeMustHaveDefaultParameterlessCtor); - } - } - - // used by client to create the first query - internal TableQuery(CloudTable table) - : base() - { - this.queryProvider = new TableQueryProvider(table); - - // TODO can base expression be non constant? - this.queryExpression = - new ResourceSetExpression(typeof(IOrderedQueryable), null, Expression.Constant("0"), typeof(TElement), null, CountOption.None, null, null); - } - - // Used by iqueryable on subsequent expression updates to update expression / provider - internal TableQuery(Expression queryExpression, TableQueryProvider queryProvider) - { - this.queryProvider = queryProvider; - this.queryExpression = queryExpression; - } - - #endregion - - #region Public Execution Methods - - /// - /// Executes a query on a table, using the specified and . - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection, specialized for type TElement, of the results of executing the query. - [DoesServiceRequest] - public IEnumerable Execute(TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - if (this.queryProvider == null) - { - throw new InvalidOperationException(SR.TableQueryMustHaveQueryProvider); - } - - ExecutionInfo executionInfo = this.Bind(); - executionInfo.RequestOptions = requestOptions ?? executionInfo.RequestOptions; - executionInfo.OperationContext = operationContext ?? executionInfo.OperationContext; - - if (executionInfo.Resolver != null) - { - // Execute the query. - return this.ExecuteInternal(this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.Resolver, executionInfo.RequestOptions, executionInfo.OperationContext); - } - else - { - return this.ExecuteInternal(this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.RequestOptions, executionInfo.OperationContext); - } - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteSegmented(TableContinuationToken currentToken, AsyncCallback callback, object state) - { - return this.BeginExecuteSegmented(currentToken, null /* RequestOptions */, null /* OperationContext */, callback, state); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// An object for tracking the current operation. - /// The callback delegate that will receive notification when the asynchronous operation completes. - /// A user-defined object that will be passed to the callback delegate. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An that references the asynchronous operation. - [DoesServiceRequest] - public ICancellableAsyncResult BeginExecuteSegmented(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - if (this.queryProvider == null) - { - throw new InvalidOperationException(SR.TableQueryMustHaveQueryProvider); - } - - ExecutionInfo executionInfo = this.Bind(); - executionInfo.RequestOptions = requestOptions == null ? executionInfo.RequestOptions : requestOptions; - executionInfo.OperationContext = operationContext == null ? executionInfo.OperationContext : operationContext; - - if (executionInfo.Resolver != null) - { - // Execute the query. - return this.BeginExecuteQuerySegmentedInternal( - currentToken, - this.queryProvider.Table.ServiceClient, - this.queryProvider.Table.Name, - executionInfo.Resolver, - executionInfo.RequestOptions, - executionInfo.OperationContext, - callback, - state); - } - else - { - return this.BeginExecuteQuerySegmentedInternal( - currentToken, - this.queryProvider.Table.ServiceClient, - this.queryProvider.Table.Name, - executionInfo.RequestOptions, - executionInfo.OperationContext, - callback, - state); - } - } - - /// - /// Ends an asynchronous operation to execute a query and return the results as a result segment. - /// - /// The reference to the pending asynchronous request to finish. - /// A result segment containing objects of type . - public TableQuerySegment EndExecuteSegmented(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - -#if TASK - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// A of object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken) - { - return this.ExecuteSegmentedAsync(currentToken, CancellationToken.None); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null./// A to observe while waiting for a task to complete. - /// A of object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteSegmented, this.EndExecuteSegmented, currentToken, cancellationToken); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// An object for tracking the current operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// A of object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext) - { - return this.ExecuteSegmentedAsync(currentToken, requestOptions, operationContext, CancellationToken.None); - } - - /// - /// Begins an asynchronous operation to execute a query and return the results as a result segment. - /// - /// A continuation token returned by a previous listing operation, can be null. - /// An object for tracking the current operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// A to observe while waiting for a task to complete. - /// A of object that represents the current operation. - [DoesServiceRequest] - public Task> ExecuteSegmentedAsync(TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) - { - return AsyncExtensions.TaskFromApm(this.BeginExecuteSegmented, this.EndExecuteSegmented, currentToken, requestOptions, operationContext, cancellationToken); - } -#endif - -#if SYNC - /// - /// Queries a table in segmented mode using the specified continuation token, , and . - /// - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A , specialized for type TElement, containing the results of executing the query. - [DoesServiceRequest] - public TableQuerySegment ExecuteSegmented(TableContinuationToken continuationToken, TableRequestOptions requestOptions = null, OperationContext operationContext = null) - { - if (this.queryProvider == null) - { - throw new InvalidOperationException(SR.TableQueryMustHaveQueryProvider); - } - - ExecutionInfo executionInfo = this.Bind(); - executionInfo.RequestOptions = requestOptions == null ? executionInfo.RequestOptions : requestOptions; - executionInfo.OperationContext = operationContext == null ? executionInfo.OperationContext : operationContext; - - if (executionInfo.Resolver != null) - { - // Execute the query. - return this.ExecuteQuerySegmentedInternal(continuationToken, this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.Resolver, executionInfo.RequestOptions, executionInfo.OperationContext); - } - else - { - return this.ExecuteQuerySegmentedInternal(continuationToken, this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.RequestOptions, executionInfo.OperationContext); - } - } - -#endif - #endregion - - #region IQueryable implementation - /// - /// Returns an enumerator that iterates through the . - /// - /// An for the . - public IEnumerator GetEnumerator() - { - if (this.Expression == null) - { - TableRequestOptions defaultRequestOptions = TableRequestOptions.ApplyDefaults(null, this.queryProvider.Table.ServiceClient); - - // TODO should we just throw here? - // Standard Query Mode - return this.ExecuteInternal(this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, defaultRequestOptions, null /* OperationContext */).GetEnumerator(); - } - else - { - ExecutionInfo executionInfo = this.Bind(); - - if (executionInfo.Resolver != null) - { - // Execute the query. - return this.ExecuteInternal(this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.Resolver, executionInfo.RequestOptions, executionInfo.OperationContext).GetEnumerator(); - } - else - { - return this.ExecuteInternal(this.queryProvider.Table.ServiceClient, this.queryProvider.Table.Name, executionInfo.RequestOptions, executionInfo.OperationContext).GetEnumerator(); - } - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - - /// - /// Gets the type of the element(s) that are returned when the expression tree is executed. - /// - public Type ElementType - { - get { return typeof(TElement); } - } - - /// - /// Gets the expression tree. - /// - public Expression Expression - { - get { return this.queryExpression; } - } - - /// - /// Gets the query provider that is associated with this data source. - /// - public IQueryProvider Provider - { - get { return this.queryProvider; } - } - - internal ExecutionInfo Bind() - { - ExecutionInfo retVal = new ExecutionInfo(); - - // IQueryable impl - if (this.Expression != null) - { - Dictionary normalizerRewrites = new Dictionary(ReferenceEqualityComparer.Instance); - - // Step 1. Evaluate any local evaluatable expressions ( lambdas etc) - Expression partialEvaluatedExpression = Evaluator.PartialEval(this.Expression); - - // Step 2. Normalize expression, replace String Comparisons etc. - Expression normalizedExpression = ExpressionNormalizer.Normalize(partialEvaluatedExpression, normalizerRewrites); - - // Step 3. Bind Expression, Analyze predicates and create query option expressions. End result is a single ResourceSetExpression - Expression boundExpression = ResourceBinder.Bind(normalizedExpression); - - // Step 4. Parse the Bound expression into sub components, i.e. take count, filter, select columns, request options, opcontext, etc. - ExpressionParser parser = new ExpressionParser(); - parser.Translate(boundExpression); - - // Step 5. Store query components & params - this.TakeCount = parser.TakeCount; - this.FilterString = parser.FilterString; - this.SelectColumns = parser.SelectColumns; - retVal.RequestOptions = parser.RequestOptions; - retVal.OperationContext = parser.OperationContext; - - // Step 6. If projection & no resolver then generate a resolver to perform the projection - if (parser.Resolver == null) - { - if (parser.Projection != null && parser.Projection.Selector != ProjectionQueryOptionExpression.DefaultLambda) - { - Type intermediateType = parser.Projection.Selector.Parameters[0].Type; - - // Convert Expression to take type object as input to allow for direct invocation. - ParameterExpression paramExpr = Expression.Parameter(typeof(object)); - - Func projectorFunc = Expression.Lambda>( - Expression.Invoke(parser.Projection.Selector, Expression.Convert(paramExpr, intermediateType)), paramExpr).Compile(); - - // Generate a resolver to do the projection. - retVal.Resolver = (pk, rk, ts, props, etag) => - { - // Parse to intermediate type - ITableEntity intermediateObject = (ITableEntity)EntityUtilities.InstantiateEntityFromType(intermediateType); - intermediateObject.PartitionKey = pk; - intermediateObject.RowKey = rk; - intermediateObject.Timestamp = ts; - intermediateObject.ReadEntity(props, parser.OperationContext); - intermediateObject.ETag = etag; - - // Invoke lambda expression - return projectorFunc(intermediateObject); - }; - } - else - { - // No op - No resolver or projection specified. - } - } - else - { - retVal.Resolver = (EntityResolver)parser.Resolver.Value; - } - } - - retVal.RequestOptions = TableRequestOptions.ApplyDefaults(retVal.RequestOptions, this.queryProvider.Table.ServiceClient); - retVal.OperationContext = retVal.OperationContext ?? new OperationContext(); - return retVal; - } - - internal class ExecutionInfo - { - public OperationContext OperationContext { get; set; } - - public TableRequestOptions RequestOptions { get; set; } - - public EntityResolver Resolver { get; set; } - } - #endregion - - #region Internal Impl - - internal IEnumerable ExecuteInternal(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = CommonUtility.LazyEnumerable( - (continuationToken) => - { - TableQuerySegment seg = -#if SYNC - this.ExecuteQuerySegmentedInternal((TableContinuationToken)continuationToken, client, tableName, modifiedOptions, operationContext); -#else - this.EndExecuteQuerySegmentedInternal(this.BeginExecuteQuerySegmentedInternal((TableContinuationToken)continuationToken, client, tableName, modifiedOptions, operationContext, null /* callback */, null /* state */)); -#endif - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.TakeCount.HasValue ? this.TakeCount.Value : long.MaxValue); - - return enumerable; - } - -#if SYNC - internal TableQuerySegment ExecuteQuerySegmentedInternal(TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, EntityUtilities.ResolveEntityByType, modifiedOptions); - - return Executor.ExecuteSync(cmdToExecute, modifiedOptions.RetryPolicy, operationContext); - } -#endif - - internal ICancellableAsyncResult BeginExecuteQuerySegmentedInternal(TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - QueryImpl(this, token, client, tableName, EntityUtilities.ResolveEntityByType, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - internal TableQuerySegment EndExecuteQuerySegmentedInternal(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - - internal IEnumerable ExecuteInternal(CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = CommonUtility.LazyEnumerable( - (continuationToken) => - { - TableQuerySegment seg = -#if SYNC - this.ExecuteQuerySegmentedInternal((TableContinuationToken)continuationToken, client, tableName, resolver, modifiedOptions, operationContext); -#else - this.EndExecuteQuerySegmentedInternal(this.BeginExecuteQuerySegmentedInternal((TableContinuationToken)continuationToken, client, tableName, resolver, modifiedOptions, operationContext, null /* callback */, null /* state */)); -#endif - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - -#if SYNC - internal TableQuerySegment ExecuteQuerySegmentedInternal(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, resolver, modifiedOptions); - - return Executor.ExecuteSync(cmdToExecute, modifiedOptions.RetryPolicy, operationContext); - } -#endif - internal ICancellableAsyncResult BeginExecuteQuerySegmentedInternal(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - QueryImpl(this, token, client, tableName, resolver, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - internal TableQuerySegment EndExecuteQuerySegmentedInternal(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - - private static RESTCommand> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions) - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand> queryCmd = new RESTCommand>(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.SignRequest = client.AuthenticationHandler.SignRequest; - queryCmd.BuildRequestDelegate = TableOperationHttpWebRequestFactory.BuildRequestForTableQuery; - - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp != null ? resp.StatusCode : HttpStatusCode.Unused, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ResultSegment resSeg = TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(cmd.ResponseStream, resolver.Invoke, resp); - return new TableQuerySegment(resSeg); - }; - - return queryCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQueryNonGeneric.cs b/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQueryNonGeneric.cs deleted file mode 100644 index 932bd3090c7c1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/DotNetCommon/Table/TableQueryNonGeneric.cs +++ /dev/null @@ -1,213 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Net; - - public partial class TableQuery - { - /// - /// Represents a query against a specified table. - /// - /// A instance aggregates the query parameters to use when the query is executed. One of the executeQuery or executeQuerySegmented methods - /// of must be called to execute the query. The parameters are encoded and passed to the server when the table query is executed. - public TableQuery() - { - } - - /// - /// Specifies the names of the entity properties to return when the query is executed against the table. - /// - /// The Project clause is optional on a query, used to limit the properties returned from the server. By default, a query will return all properties from the entity. - /// The entity type of the query. - /// The entity instance to project off of. - /// A list of string objects containing the names of the entity properties to return when the query is executed. - /// A instance set with the entity properties to return. - public static T Project(T entity, params string[] columns) - { - return entity; - } - - #region Impl -#if SYNC - internal IEnumerable Execute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = CommonUtility.LazyEnumerable( - (continuationToken) => - { - TableQuerySegment seg = this.ExecuteQuerySegmented((TableContinuationToken)continuationToken, client, tableName, modifiedOptions, operationContext); - - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - - internal IEnumerable Execute(CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = CommonUtility.LazyEnumerable( - (continuationToken) => - { - TableQuerySegment seg = this.ExecuteQuerySegmented((TableContinuationToken)continuationToken, client, tableName, resolver, modifiedOptions, operationContext); - - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - - internal TableQuerySegment ExecuteQuerySegmented(TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, modifiedOptions); - - return Executor.ExecuteSync(cmdToExecute, modifiedOptions.RetryPolicy, operationContext); - } - - internal TableQuerySegment ExecuteQuerySegmented(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, resolver, modifiedOptions); - - return Executor.ExecuteSync(cmdToExecute, modifiedOptions.RetryPolicy, operationContext); - } -#endif - - [DoesServiceRequest] - internal ICancellableAsyncResult BeginExecuteQuerySegmented(TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - QueryImpl(this, token, client, tableName, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - [DoesServiceRequest] - internal ICancellableAsyncResult BeginExecuteQuerySegmented(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext, AsyncCallback callback, object state) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - return Executor.BeginExecuteAsync( - QueryImpl(this, token, client, tableName, resolver, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - callback, - state); - } - - internal TableQuerySegment EndExecuteQuerySegmented(IAsyncResult asyncResult) - { - return Executor.EndExecuteAsync>(asyncResult); - } - - private static RESTCommand> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand> queryCmd = new RESTCommand>(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.SignRequest = client.AuthenticationHandler.SignRequest; - queryCmd.BuildRequestDelegate = TableOperationHttpWebRequestFactory.BuildRequestForTableQuery; - - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp != null ? resp.StatusCode : HttpStatusCode.Unused, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ResultSegment resSeg = TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(cmd.ResponseStream, EntityUtilities.ResolveDynamicEntity, resp); - return new TableQuerySegment(resSeg); - }; - - return queryCmd; - } - - private static RESTCommand> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions) - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand> queryCmd = new RESTCommand>(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.SignRequest = client.AuthenticationHandler.SignRequest; - queryCmd.BuildRequestDelegate = TableOperationHttpWebRequestFactory.BuildRequestForTableQuery; - - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp != null ? resp.StatusCode : HttpStatusCode.Unused, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = (cmd, resp, ctx) => - { - ResultSegment resSeg = TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(cmd.ResponseStream, resolver.Invoke, resp); - return new TableQuerySegment(resSeg); - }; - - return queryCmd; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/NoOpAuthenticationHttpHandler.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/NoOpAuthenticationHttpHandler.cs deleted file mode 100644 index 034b176594229..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/NoOpAuthenticationHttpHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using System; - using System.Net.Http; - - internal sealed class NoOpAuthenticationHttpHandler : HttpClientHandler - { - public NoOpAuthenticationHttpHandler() - { - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/SharedKeyAuthenticationHttpHandler.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/SharedKeyAuthenticationHttpHandler.cs deleted file mode 100644 index f645ea1ba39a8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Auth/Protocol/SharedKeyAuthenticationHttpHandler.cs +++ /dev/null @@ -1,69 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Auth.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Globalization; - using System.Net.Http; - using System.Net.Http.Headers; - using System.Threading; - using System.Threading.Tasks; - - internal sealed class SharedKeyAuthenticationHttpHandler : HttpClientHandler - { - private readonly ICanonicalizer canonicalizer; - private readonly StorageCredentials credentials; - private readonly string accountName; - - public SharedKeyAuthenticationHttpHandler(ICanonicalizer canonicalizer, StorageCredentials credentials, string accountName) - { - this.canonicalizer = canonicalizer; - this.credentials = credentials; - this.accountName = accountName; - } - - protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - string dateString = HttpWebUtility.ConvertDateTimeToHttpString(DateTimeOffset.UtcNow); - request.Headers.Add(Constants.HeaderConstants.Date, dateString); - - if (this.credentials.IsSharedKey) - { - string message = this.canonicalizer.CanonicalizeHttpRequest(request, this.accountName); - - StorageAccountKey accountKey = this.credentials.Key; - - string signature = CryptoUtility.ComputeHmac256(accountKey.KeyValue, message); - - if (!string.IsNullOrEmpty(accountKey.KeyName)) - { - request.Headers.Add(Constants.HeaderConstants.KeyNameHeader, accountKey.KeyName); - } - - request.Headers.Authorization = new AuthenticationHeaderValue( - this.canonicalizer.AuthorizationScheme, - string.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.credentials.AccountName, signature)); - } - - return base.SendAsync(request, cancellationToken); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStream.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStream.cs deleted file mode 100644 index 05bc528352b9a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStream.cs +++ /dev/null @@ -1,152 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.IO; - using System.Threading; - using System.Threading.Tasks; - using Windows.Storage.Streams; - - /// - /// Provides an input stream to read a given blob resource. - /// - internal sealed class BlobReadStream : BlobReadStreamBase, IContentTypeProvider - { - /// - /// Initializes a new instance of the class. - /// - /// Blob reference to read from. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - internal BlobReadStream(ICloudBlob blob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(blob, accessCondition, options, operationContext) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Another BlobReadStream instance to clone. - internal BlobReadStream(BlobReadStream otherStream) - : this(otherStream.blob, otherStream.accessCondition, otherStream.options, otherStream.operationContext) - { - } - - /// - /// Gets the format of the data. - /// - /// The format of the data. - public string ContentType - { - get - { - return this.blobProperties.ContentType; - } - } - - /// - /// Reads a sequence of bytes from the current stream and advances the - /// position within the stream by the number of bytes read. - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// The total number of bytes read into the buffer. This can be - /// less than the number of bytes requested if that many bytes are not - /// currently available, or zero (0) if the end of the stream has been reached. - public override int Read(byte[] buffer, int offset, int count) - { - return this.ReadAsync(buffer, offset, count, CancellationToken.None).Result; - } - - /// - /// Asynchronously reads a sequence of bytes from the current stream, advances the - /// position within the stream by the number of bytes read, and monitors cancellation requests. - /// - /// In the returned object, the value of the integer - /// parameter contains the total number of bytes read into the buffer. The result value can be - /// less than the number of bytes requested if the number of bytes currently available is less - /// than the requested number, or it can be 0 (zero) if the end of the stream has been reached. - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous read operation. - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - if (this.lastException != null) - { - throw this.lastException; - } - - if ((this.currentOffset == this.Length) || (count == 0)) - { - return 0; - } - - int readCount = this.ConsumeBuffer(buffer, offset, count); - if (readCount > 0) - { - return readCount; - } - - return await this.DispatchReadAsync(buffer, offset, count); - } - - /// - /// Dispatches a sync read operation that either reads from the cache or makes a call to - /// the server. - /// - /// The buffer to read the data into. - /// The byte offset in buffer at which to begin writing - /// data read from the stream. - /// The maximum number of bytes to read. - /// Number of bytes read from the stream. - private async Task DispatchReadAsync(byte[] buffer, int offset, int count) - { - try - { - this.internalBuffer.SetLength(0); - await this.blob.DownloadRangeToStreamAsync( - this.internalBuffer.AsOutputStream(), - this.currentOffset, - this.GetReadSize(), - this.accessCondition, - this.options, - this.operationContext); - - this.internalBuffer.Seek(0, SeekOrigin.Begin); - return this.ConsumeBuffer(buffer, offset, count); - } - catch (Exception e) - { - this.lastException = e; - throw; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStreamHelper.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStreamHelper.cs deleted file mode 100644 index b35c2e9641849..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobReadStreamHelper.cs +++ /dev/null @@ -1,198 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.IO; - using Windows.Foundation; - using Windows.Storage.Streams; - - /// - /// BlobReadStream class is based on Stream, but all RT APIs need to return - /// IRandomAccessStream that cannot be easily converted from a Stream object. - /// This class implements IRandomAccessStream and acts like a proxy between - /// the caller and the actual Stream implementation. - /// - internal sealed class BlobReadStreamHelper : IRandomAccessStreamWithContentType - { - private BlobReadStream originalStream; - private IInputStream originalStreamAsInputStream; - - /// - /// Initializes a new instance of the BlobReadStreamHelper class. - /// - /// Blob reference to read from - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - internal BlobReadStreamHelper(ICloudBlob blob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.originalStream = new BlobReadStream(blob, accessCondition, options, operationContext); - this.originalStreamAsInputStream = this.originalStream.AsInputStream(); - } - - /// - /// Initializes a new instance of the BlobReadStreamHelper class. - /// - /// An instance of BlobReadStream class that this helper should use. - private BlobReadStreamHelper(BlobReadStream otherStream) - { - this.originalStream = otherStream; - this.originalStreamAsInputStream = this.originalStream.AsInputStream(); - } - - /// - /// Gets a value that indicates whether the stream can be read from. - /// - public bool CanRead - { - get - { - return this.originalStream.CanRead; - } - } - - /// - /// Gets a value that indicates whether the stream can be written to. - /// - public bool CanWrite - { - get - { - return false; - } - } - - /// - /// Gets the format of the data. - /// - public string ContentType - { - get - { - return this.originalStream.ContentType; - } - } - - /// - /// Creates a new instance of a IRandomAccessStream over the same resource as the current stream. - /// - /// The new stream. The initial, internal position of the stream is 0. - public IRandomAccessStream CloneStream() - { - BlobReadStream clonedStream = new BlobReadStream(this.originalStream); - return new BlobReadStreamHelper(clonedStream); - } - - /// - /// Returns an input stream at a specified location in a stream. - /// - /// The location in the stream at which to begin. - /// The input stream. - public IInputStream GetInputStreamAt(ulong position) - { - BlobReadStream clonedStream = new BlobReadStream(this.originalStream); - clonedStream.Seek((long)position, SeekOrigin.Begin); - return clonedStream.AsInputStream(); - } - - /// - /// This operation is not supported in BlobReadStreamHelper. - /// - /// Not used. - /// Not applicable. - public IOutputStream GetOutputStreamAt(ulong position) - { - throw new NotSupportedException(); - } - - /// - /// Gets the byte offset of the stream. - /// - public ulong Position - { - get - { - return (ulong)this.originalStream.Position; - } - } - - /// - /// Sets the position of the stream to the specified value. - /// - /// The new position of the stream. - public void Seek(ulong position) - { - this.originalStream.Seek((long)position, SeekOrigin.Begin); - } - - /// - /// Gets or sets the size of the random access stream. - /// - public ulong Size - { - get - { - return (ulong)this.originalStream.Length; - } - - set - { - this.originalStream.SetLength((long)value); - } - } - - /// - /// Releases the underlying stream. - /// - public void Dispose() - { - this.originalStream.Dispose(); - } - - /// - /// Returns an asynchronous byte reader object. - /// - /// The buffer into which the asynchronous read operation places the bytes that are read. - /// The number of bytes to read that is less than or equal to the Capacity value. - /// Specifies the type of the asynchronous read operation. - /// The asynchronous operation. - public IAsyncOperationWithProgress ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) - { - return this.originalStreamAsInputStream.ReadAsync(buffer, count, options); - } - - /// - /// This operation is not supported in BlobReadStreamHelper. - /// - /// Not applicable. - public IAsyncOperation FlushAsync() - { - throw new NotSupportedException(); - } - - /// - /// This operation is not supported in BlobReadStreamHelper. - /// - /// Not used. - /// Not applicable. - public IAsyncOperationWithProgress WriteAsync(IBuffer buffer) - { - throw new NotSupportedException(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStream.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStream.cs deleted file mode 100644 index ec2106e46fcc9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStream.cs +++ /dev/null @@ -1,331 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.IO; - using System.Threading; - using System.Threading.Tasks; - - internal sealed class BlobWriteStream : BlobWriteStreamBase - { - /// - /// Initializes a new instance of the BlobWriteStream class for a block blob. - /// - /// Blob reference to write to. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - internal BlobWriteStream(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(blockBlob, accessCondition, options, operationContext) - { - } - - /// - /// Initializes a new instance of the BlobWriteStream class for a page blob. - /// - /// Blob reference to write to. - /// Size of the page blob. - /// Use true if the page blob is newly created, false otherwise. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - internal BlobWriteStream(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - : base(pageBlob, pageBlobSize, createNew, accessCondition, options, operationContext) - { - } - - /// - /// Sets the position within the current stream. - /// - /// A byte offset relative to the origin parameter. - /// A value of type SeekOrigin indicating the reference - /// point used to obtain the new position. - /// The new position within the current stream. - public override long Seek(long offset, SeekOrigin origin) - { - long oldOffset = this.currentOffset; - long newOffset = this.GetNewOffset(offset, origin); - - if (oldOffset != newOffset) - { - if (this.blobMD5 != null) - { - this.blobMD5.Dispose(); - this.blobMD5 = null; - } - - this.Flush(); - } - - this.currentOffset = newOffset; - this.currentPageOffset = newOffset; - return this.currentOffset; - } - - /// - /// Writes a sequence of bytes to the current stream and advances the current - /// position within this stream by the number of bytes written. - /// - /// An array of bytes. This method copies count bytes from - /// buffer to the current stream. - /// The zero-based byte offset in buffer at which to begin - /// copying bytes to the current stream. - /// The number of bytes to be written to the current stream. - public override void Write(byte[] buffer, int offset, int count) - { - this.WriteAsync(buffer, offset, count).Wait(); - } - - /// - /// Asynchronously writes a sequence of bytes to the current stream, advances the current - /// position within this stream by the number of bytes written, and monitors cancellation requests. - /// - /// An array of bytes. This method copies count bytes from - /// buffer to the current stream. - /// The zero-based byte offset in buffer at which to begin - /// copying bytes to the current stream. - /// The number of bytes to be written to the current stream. - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous write operation. - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - CommonUtility.AssertNotNull("buffer", buffer); - CommonUtility.AssertInBounds("offset", offset, 0, buffer.Length); - CommonUtility.AssertInBounds("count", count, 0, buffer.Length - offset); - - if (this.lastException != null) - { - throw this.lastException; - } - - if (this.committed) - { - throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); - } - - if (this.blobMD5 != null) - { - this.blobMD5.UpdateHash(buffer, offset, count); - } - - this.currentOffset += count; - while (count > 0) - { - int maxBytesToWrite = this.streamWriteSizeInBytes - (int)this.internalBuffer.Length; - int bytesToWrite = Math.Min(count, maxBytesToWrite); - - this.internalBuffer.Write(buffer, offset, bytesToWrite); - if (this.blockMD5 != null) - { - this.blockMD5.UpdateHash(buffer, offset, bytesToWrite); - } - - count -= bytesToWrite; - offset += bytesToWrite; - - if (bytesToWrite == maxBytesToWrite) - { - await this.DispatchWriteAsync(); - } - } - } - - /// - /// Clears all buffers for this stream and causes any buffered data to be written to the underlying blob. - /// - public override void Flush() - { - this.FlushAsync().Wait(); - } - - /// - /// Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying device, and monitors cancellation requests. - /// - /// The token to monitor for cancellation requests. - /// A task that represents the asynchronous flush operation. - public override async Task FlushAsync(CancellationToken cancellationToken) - { - if (this.lastException != null) - { - throw this.lastException; - } - - if (this.committed) - { - throw new InvalidOperationException(SR.BlobStreamAlreadyCommitted); - } - - await this.DispatchWriteAsync(); - await Task.Run(() => this.noPendingWritesEvent.Wait(), cancellationToken); - - if (this.lastException != null) - { - throw this.lastException; - } - } - - /// - /// Releases the blob resources used by the Stream. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool disposing) - { - if (!this.disposed) - { - this.disposed = true; - - if (disposing) - { - if (!this.committed) - { - this.CommitAsync().Wait(); - } - } - } - - base.Dispose(disposing); - } - - /// - /// Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying blob, and commits the blob. - /// - /// A task that represents the asynchronous commit operation. - public async Task CommitAsync() - { - await this.FlushAsync(); - this.committed = true; - - try - { - if (this.blockBlob != null) - { - if (this.blobMD5 != null) - { - this.blockBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - } - - await this.blockBlob.PutBlockListAsync(this.blockList, this.accessCondition, this.options, this.operationContext); - } - else - { - if (this.blobMD5 != null) - { - this.pageBlob.Properties.ContentMD5 = this.blobMD5.ComputeHash(); - await this.pageBlob.SetPropertiesAsync(this.accessCondition, this.options, this.operationContext); - } - } - } - catch (Exception e) - { - this.lastException = e; - throw; - } - } - - /// - /// Asynchronously dispatches a write operation. - /// - /// A task that represents the asynchronous write operation. - private async Task DispatchWriteAsync() - { - if (this.internalBuffer.Length == 0) - { - return; - } - - MultiBufferMemoryStream bufferToUpload = this.internalBuffer; - this.internalBuffer = new MultiBufferMemoryStream(this.Blob.ServiceClient.BufferManager); - bufferToUpload.Seek(0, SeekOrigin.Begin); - - string bufferMD5 = null; - if (this.blockMD5 != null) - { - bufferMD5 = this.blockMD5.ComputeHash(); - this.blockMD5.Dispose(); - this.blockMD5 = new MD5Wrapper(); - } - - if (this.blockBlob != null) - { - string blockId = this.GetCurrentBlockId(); - this.blockList.Add(blockId); - await this.WriteBlockAsync(bufferToUpload, blockId, bufferMD5); - } - else - { - if ((bufferToUpload.Length % Constants.PageSize) != 0) - { - this.lastException = new IOException(SR.InvalidPageSize); - throw this.lastException; - } - - long offset = this.currentPageOffset; - this.currentPageOffset += bufferToUpload.Length; - await this.WritePagesAsync(bufferToUpload, offset, bufferMD5); - } - } - - /// - /// Starts an asynchronous PutBlock operation as soon as the parallel - /// operation semaphore becomes available. - /// - /// Data to be uploaded - /// Block ID - /// A task that represents the asynchronous write operation. - private async Task WriteBlockAsync(Stream blockData, string blockId, string blockMD5) - { - this.noPendingWritesEvent.Increment(); - await this.parallelOperationSemaphore.WaitAsync(); - Task putBlockTask = this.blockBlob.PutBlockAsync(blockId, blockData.AsInputStream(), blockMD5, this.accessCondition, this.options, this.operationContext).AsTask().ContinueWith(task => - { - if (task.Exception != null) - { - this.lastException = task.Exception; - } - - this.noPendingWritesEvent.Decrement(); - this.parallelOperationSemaphore.Release(); - }); - } - - /// - /// Starts an asynchronous WritePages operation as soon as the parallel - /// operation semaphore becomes available. - /// - /// Data to be uploaded - /// Offset within the page blob - /// A task that represents the asynchronous write operation. - private async Task WritePagesAsync(Stream pageData, long offset, string contentMD5) - { - this.noPendingWritesEvent.Increment(); - await this.parallelOperationSemaphore.WaitAsync(); - Task writePagesTask = this.pageBlob.WritePagesAsync(pageData.AsInputStream(), offset, contentMD5, this.accessCondition, this.options, this.operationContext).AsTask().ContinueWith(task => - { - if (task.Exception != null) - { - this.lastException = task.Exception; - } - - this.noPendingWritesEvent.Decrement(); - this.parallelOperationSemaphore.Release(); - }); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStreamHelper.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStreamHelper.cs deleted file mode 100644 index 74f1c3f4dcb04..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/BlobWriteStreamHelper.cs +++ /dev/null @@ -1,201 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.IO; - using Windows.Foundation; - using Windows.Storage.Streams; - - /// - /// BlobWriteStream class is based on Stream, but all RT APIs need to return - /// IRandomAccessStream that cannot be easily converted from a Stream object. - /// This class implements IRandomAccessStream and acts like a proxy between - /// the caller and the actual Stream implementation. - /// - internal class BlobWriteStreamHelper : ICloudBlobStream - { - private BlobWriteStream originalStream; - private IOutputStream originalStreamAsOutputStream; - - /// - /// Initializes a new instance of the BlobWriteStreamHelper class for a block blob. - /// - /// Blob reference to write to. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - internal BlobWriteStreamHelper(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.originalStream = new BlobWriteStream(blockBlob, accessCondition, options, operationContext); - this.originalStreamAsOutputStream = this.originalStream.AsOutputStream(); - } - - /// - /// Initializes a new instance of the BlobWriteStreamHelper class for a page blob. - /// - /// Blob reference to write to. - /// Size of the page blob. - /// Use true if the page blob is newly created, false otherwise. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - internal BlobWriteStreamHelper(CloudPageBlob pageBlob, long pageBlobSize, bool createNew, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.originalStream = new BlobWriteStream(pageBlob, pageBlobSize, createNew, accessCondition, options, operationContext); - this.originalStreamAsOutputStream = this.originalStream.AsOutputStream(); - } - - /// - /// Gets a value that indicates whether the stream can be read from. - /// - public bool CanRead - { - get - { - return false; - } - } - - /// - /// Gets a value that indicates whether the stream can be written to. - /// - public bool CanWrite - { - get - { - return this.originalStream.CanWrite; - } - } - - /// - /// Gets the byte offset of the stream. - /// - public ulong Position - { - get - { - return (ulong)this.originalStream.Position; - } - } - - /// - /// Gets or sets the size of the random access stream. - /// - public ulong Size - { - get - { - return (ulong)this.originalStream.Length; - } - - set - { - this.originalStream.SetLength((long)value); - } - } - - /// - /// Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying blob, and commits the blob. - /// - /// An that represents an asynchronous action. - public IAsyncAction CommitAsync() - { - return this.originalStream.CommitAsync().AsAsyncAction(); - } - - /// - /// Returns an asynchronous byte reader object. - /// - /// The buffer into which the asynchronous read operation places the bytes that are read. - /// The number of bytes to read. - /// Specifies the type of the asynchronous read operation. - /// The asynchronous operation. - public IAsyncOperationWithProgress ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) - { - throw new NotSupportedException(); - } - - /// - /// Flushes data asynchronously in a sequential stream. - /// - /// The stream flush operation. - public IAsyncOperation FlushAsync() - { - return this.originalStreamAsOutputStream.FlushAsync(); - } - - /// - /// Writes data asynchronously in a sequential stream. - /// - /// The buffer into which the asynchronous writer operation writes. - /// The byte writer operation. - public IAsyncOperationWithProgress WriteAsync(IBuffer buffer) - { - return this.originalStreamAsOutputStream.WriteAsync(buffer); - } - - /// - /// Releases the blob resources used by the stream. - /// - public void Dispose() - { - if (this.originalStream != null) - { - this.originalStream.Dispose(); - this.originalStream = null; - } - } - - /// - /// Creates a new instance of a IRandomAccessStream over the same resource as the current stream. - /// - /// The new stream. - public IRandomAccessStream CloneStream() - { - throw new NotImplementedException(); - } - - /// - /// Returns an input stream at a specified location in a stream. - /// - /// The location in the stream at which to begin. - /// The input stream. - public IInputStream GetInputStreamAt(ulong position) - { - throw new NotImplementedException(); - } - - /// - /// Returns an output stream at a specified location in a stream. - /// - /// The location in the output stream at which to begin. - /// The output stream. - public IOutputStream GetOutputStreamAt(ulong position) - { - throw new NotImplementedException(); - } - - /// - /// Sets the position of the stream to the specified value. - /// - /// The new position of the stream. - public void Seek(ulong position) - { - this.originalStream.Seek((long)position, SeekOrigin.Begin); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobClient.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobClient.cs deleted file mode 100644 index 7b4a090b67d26..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobClient.cs +++ /dev/null @@ -1,415 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Auth; - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - - /// - /// Provides a client-side logical representation of the Windows Azure Blob Service. This client is used to configure and execute requests against 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 sealed partial class CloudBlobClient - { - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - this.authenticationScheme = value; - } - } - - /// - /// Gets the authentication handler used to sign requests. - /// - /// Authentication handler. - internal HttpClientHandler AuthenticationHandler - { - get - { - HttpClientHandler authenticationHandler; - if (this.Credentials.IsSharedKey) - { - authenticationHandler = new SharedKeyAuthenticationHttpHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - authenticationHandler = new NoOpAuthenticationHttpHandler(); - } - - return authenticationHandler; - } - } - - /// - /// Returns a result segment containing a collection of containers. - /// - /// A continuation token returned by a previous listing operation. - /// A result segment of containers. - [DoesServiceRequest] - public IAsyncOperation ListContainersSegmentedAsync(BlobContinuationToken currentToken) - { - return this.ListContainersSegmentedAsync(null /* prefix */, ContainerListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of containers. - /// - /// A continuation token returned by a previous listing operation. - /// A result segment of containers. - [DoesServiceRequest] - public IAsyncOperation ListContainersSegmentedAsync(string prefix, BlobContinuationToken currentToken) - { - return this.ListContainersSegmentedAsync(prefix, ContainerListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of containers - /// whose names begin with the specified prefix. - /// - /// The container name prefix. - /// A value that indicates whether to return container metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A result segment of containers. - [DoesServiceRequest] - public IAsyncOperation ListContainersSegmentedAsync(string prefix, ContainerListingDetails detailsIncluded, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - ResultSegment resultSegment = await Executor.ExecuteAsync( - this.ListContainersImpl(prefix, detailsIncluded, currentToken, maxResults, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token); - - return new ContainerResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - }); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The container name prefix. - /// The continuation token. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The container name prefix. - /// Whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - string containerName; - string listingPrefix; - CloudBlobClient.ParseUserPrefix(prefix, out containerName, out listingPrefix); - - CloudBlobContainer container = this.GetContainerReference(containerName); - return container.ListBlobsSegmentedAsync(listingPrefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext); - } - - /// - /// Gets a reference to a blob in this container. - /// - /// The URI of the blob. - /// A reference to the blob. - [DoesServiceRequest] - public IAsyncOperation GetBlobReferenceFromServerAsync(Uri blobUri) - { - return this.GetBlobReferenceFromServerAsync(blobUri, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Gets a reference to a blob in this container. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A reference to the blob. - [DoesServiceRequest] - public IAsyncOperation GetBlobReferenceFromServerAsync(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("blobUri", blobUri); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetBlobReferenceImpl(blobUri, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Core implementation for the ListContainers method. - /// - /// The container prefix. - /// The details included. - /// The continuation token. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// A that lists the containers. - private RESTCommand> ListContainersImpl(string prefix, ContainerListingDetails detailsIncluded, BlobContinuationToken currentToken, int? maxResults, BlobRequestOptions options) - { - ListingContext listingContext = new ListingContext(prefix, maxResults) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.Credentials, this.BaseUri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.List(cmd.Uri, cmd.ServerTimeoutInSeconds, listingContext, detailsIncluded, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - ListContainersResponse listContainersResponse = new ListContainersResponse(cmd.ResponseStream); - List containersList = new List( - listContainersResponse.Containers.Select(item => new CloudBlobContainer(item.Properties, item.Metadata, item.Name, this))); - BlobContinuationToken continuationToken = null; - if (listContainersResponse.NextMarker != null) - { - continuationToken = new BlobContinuationToken() - { - NextMarker = listContainersResponse.NextMarker, - }; - } - - return new ResultSegment(containersList) - { - ContinuationToken = continuationToken, - }; - }); - }; - - return getCmd; - } - - /// - /// Implements the FetchAttributes method. The attributes are updated immediately. - /// - /// The URI of the blob. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand GetBlobReferenceImpl(Uri blobUri, AccessCondition accessCondition, BlobRequestOptions options) - { - // If the blob Uri contains SAS credentials, we need to use those - // credentials instead of this service client's stored credentials. - StorageCredentials parsedCredentials; - DateTimeOffset? parsedSnapshot; - blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot); - CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.BaseUri, parsedCredentials) : this; - - RESTCommand getCmd = new RESTCommand(client.Credentials, blobUri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = client.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, parsedSnapshot, accessCondition, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - BlobAttributes attributes = new BlobAttributes() - { - Uri = blobUri, - SnapshotTime = parsedSnapshot, - }; - - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - - switch (attributes.Properties.BlobType) - { - case BlobType.BlockBlob: - return new CloudBlockBlob(attributes, client); - - case BlobType.PageBlob: - return new CloudPageBlob(attributes, client); - - default: - throw new InvalidOperationException(); - } - }; - - return getCmd; - } - - #region Analytics - - /// - /// Gets the properties of the blob service. - /// - /// The blob service properties. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(null /* options */, null /* operationContext */); - } - - /// - /// Gets the properties of the blob service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// The blob service properties. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync(BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run( - async (token) => await Executor.ExecuteAsync( - this.GetServicePropertiesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - private RESTCommand GetServicePropertiesImpl(BlobRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - - retCmd.RetrieveResponseStream = true; - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - retCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => BlobHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)); - }; - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - /// - /// Gets the properties of the blob service. - /// - /// The blob service properties. - /// The properties of the blob service. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, null /* options */, null /* operationContext */); - } - - /// - /// Gets the properties of the blob service. - /// - /// The blob service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object that represents the context for the current operation. - /// The properties of the blob service. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties, BlobRequestOptions requestOptions, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(requestOptions, BlobType.Unspecified, this); - operationContext = operationContext ?? new OperationContext(); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetServicePropertiesImpl(properties, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(memoryStream); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.ApplyRequestOptions(requestOptions); - retCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.SetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - retCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - retCmd.RetrieveResponseStream = true; - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobContainer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobContainer.cs deleted file mode 100644 index e32bf5de518f4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobContainer.cs +++ /dev/null @@ -1,1085 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - /// - /// Represents a container in the Windows Azure Blob service. - /// - /// Containers hold directories, which are encapsulated as objects, and directories hold block blobs and page blobs. Directories can also contain sub-directories. - public sealed partial class CloudBlobContainer - { - /// - /// Creates the container. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync() - { - return this.CreateAsync(null /* options */, null /* operationContext */); - } - - /// - /// Creates the container. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateAsync(BlobContainerPublicAccessType.Off, options, operationContext); - } - - /// - /// Creates the container and specifies the level of access to the container's data. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.CreateContainerImpl(modifiedOptions, accessType), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Creates the container if it does not already exist. - /// - /// true if the container did not already exist and was created; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Creates the container if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container did not already exist and was created; otherwise false. - [DoesServiceRequest] - public IAsyncOperation CreateIfNotExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - return this.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Off, options, operationContext); - } - - /// - /// Creates the container if it does not already exist and specifies the level of access to the container's data. - /// - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container did not already exist and was created; otherwise false. - [DoesServiceRequest] - public IAsyncOperation CreateIfNotExistsAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (exists) - { - return false; - } - - try - { - await this.CreateAsync(accessType, modifiedOptions, operationContext).AsTask(token); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == BlobErrorCodeStrings.ContainerAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Deletes the container. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync() - { - return this.DeleteAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.DeleteContainerImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the container if it already exists. - /// - /// true if the container already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the container if it already exists. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (!exists) - { - return false; - } - - try - { - await this.DeleteAsync(accessCondition, modifiedOptions, operationContext).AsTask(token); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == BlobErrorCodeStrings.ContainerNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Gets a reference to a blob in this container. - /// - /// The name of the blob. - /// A reference to the blob. - [DoesServiceRequest] - public IAsyncOperation GetBlobReferenceFromServerAsync(string blobName) - { - return this.GetBlobReferenceFromServerAsync(blobName, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Gets a reference to a blob in this container. - /// - /// The name of the blob. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A reference to the blob. - [DoesServiceRequest] - public IAsyncOperation GetBlobReferenceFromServerAsync(string blobName, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("blobName", blobName); - Uri blobUri = NavigationHelper.AppendPathToUri(this.Uri, blobName); - - return this.ServiceClient.GetBlobReferenceFromServerAsync(blobUri, accessCondition, options, operationContext); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// A token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(null /* prefix */, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The container name prefix. - /// A token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(string prefix, BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(prefix, false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// The container name prefix. - /// Whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(string prefix, bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => - { - ResultSegment resultSegment = await Executor.ExecuteAsync( - this.ListBlobsImpl(prefix, maxResults, useFlatBlobListing, blobListingDetails, modifiedOptions, currentToken), - modifiedOptions.RetryPolicy, - operationContext, - token); - - return new BlobResultSegment(resultSegment.Results, (BlobContinuationToken)resultSegment.ContinuationToken); - }); - } - - /// - /// Sets permissions for the container. - /// - /// The permissions to apply to the container. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPermissionsAsync(BlobContainerPermissions permissions) - { - return this.SetPermissionsAsync(permissions, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Sets permissions for the container. - /// - /// The permissions to apply to the container. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPermissionsAsync(BlobContainerPermissions permissions, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetPermissionsImpl(permissions, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Gets the permissions settings for the container. - /// - /// The container's permissions. - [DoesServiceRequest] - public IAsyncOperation GetPermissionsAsync() - { - return this.GetPermissionsAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Gets the permissions settings for the container. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The container's permissions. - [DoesServiceRequest] - public IAsyncOperation GetPermissionsAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetPermissionsImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Checks existence of the container. - /// - /// true if the container exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync() - { - return this.ExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Checks existence of the container. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the container exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Retrieves the container's attributes. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync() - { - return this.FetchAttributesAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Retrieves the container's attributes. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.FetchAttributesImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Sets the container's user-defined metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync() - { - return this.SetMetadataAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Sets the container's user-defined metadata. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetMetadataImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Acquires a lease on this container. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.AcquireLeaseImpl(leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Renews a lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.RenewLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Changes the lease ID on this container. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.ChangeLeaseImpl(proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Releases the lease on this container. - /// - /// An object that represents the access conditions for the container, including a required lease ID. - /// A object that specifies additional options for the request. If null, default options will be used. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.ReleaseLeaseImpl(accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Breaks the current lease on this container. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. If null, default options will be used. - /// An object that represents the context for the current operation. This object is used to track requests, and to provide additional runtime information about the operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.Unspecified, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.BreakLeaseImpl(breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Generates a RESTCommand for acquiring a lease. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. This parameter must not be null. - /// A RESTCommand implementing the acquire lease operation. - internal RESTCommand AcquireLeaseImpl(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - int leaseDuration = -1; - if (leaseTime.HasValue) - { - CommonUtility.AssertInBounds("leaseTime", leaseTime.Value, TimeSpan.FromSeconds(1), TimeSpan.MaxValue); - leaseDuration = (int)leaseTime.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a RESTCommand for renewing a lease. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// This cannot be null. - /// A RESTCommand implementing the renew lease operation. - internal RESTCommand RenewLeaseImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDRenewing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a RESTCommand for changing a lease ID. - /// - /// The proposed new lease ID. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. This cannot be null. - /// A RESTCommand implementing the change lease ID operation. - internal RESTCommand ChangeLeaseImpl(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - CommonUtility.AssertNotNull("proposedLeaseId", proposedLeaseId); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDChanging, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Change, proposedLeaseId, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a RESTCommand for releasing a lease. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// This cannot be null. - /// A RESTCommand implementing the release lease operation. - internal RESTCommand ReleaseLeaseImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a RESTCommand for breaking a lease. - /// - /// The amount of time to allow the lease to remain, rounded down to seconds. - /// If null, the break period is the remainder of the current lease, or zero for infinite leases. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. Cannot be null. - /// A RESTCommand implementing the break lease operation. - internal RESTCommand BreakLeaseImpl(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options) - { - int? breakSeconds = null; - if (breakPeriod.HasValue) - { - CommonUtility.AssertInBounds("breakPeriod", breakPeriod.Value, TimeSpan.Zero, TimeSpan.MaxValue); - breakSeconds = (int)breakPeriod.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); - - int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); - if (!remainingLeaseTime.HasValue) - { - // Unexpected result from service. - throw new StorageException(cmd.CurrentResult, SR.LeaseTimeNotReceived, null /* inner */); - } - - return TimeSpan.FromSeconds(remainingLeaseTime.Value); - }; - - return putCmd; - } - - /// - /// Implementation for the Create method. - /// - /// A object that specifies additional options for the request. - /// An object that specifies whether data in the container may be accessed publicly and the level of access. - /// A that creates the container. - private RESTCommand CreateContainerImpl(BlobRequestOptions options, BlobContainerPublicAccessType accessType) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = ContainerHttpRequestMessageFactory.Create(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx, accessType); - ContainerHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Delete method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that deletes the container. - private RESTCommand DeleteContainerImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.Delete(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the FetchAttributes method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand FetchAttributesImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implementation for the Exists method. - /// - /// A object that specifies additional options for the request. - /// A that checks existence. - private RESTCommand ExistsImpl(BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, null /* accessCondition */, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - this.Properties = ContainerHttpResponseParsers.GetProperties(resp); - this.Metadata = ContainerHttpResponseParsers.GetMetadata(resp); - return true; - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand SetMetadataImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = ContainerHttpRequestMessageFactory.SetMetadata(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - ContainerHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetPermissions method. - /// - /// The permissions to set. - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand SetPermissionsImpl(BlobContainerPermissions acl, AccessCondition accessCondition, BlobRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - BlobRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.SetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, acl.PublicAccess, accessCondition, cnt, ctx); - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// An object that represents the access conditions for the container. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetPermissionsImpl(AccessCondition accessCondition, BlobRequestOptions options) - { - BlobContainerPermissions containerAcl = null; - - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.GetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - containerAcl = new BlobContainerPermissions() - { - PublicAccess = ContainerHttpResponseParsers.GetAcl(resp), - }; - return containerAcl; - }; - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - this.ParseSizeAndLastModified(resp); - return Task.Factory.StartNew(() => - { - ContainerHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, containerAcl); - return containerAcl; - }); - }; - - return getCmd; - } - - /// - /// Selects the protocol response. - /// - /// The protocol item. - /// The parsed . - private IListBlobItem SelectListBlobItem(IListBlobEntry protocolItem) - { - ListBlobEntry blob = protocolItem as ListBlobEntry; - if (blob != null) - { - BlobAttributes attributes = blob.Attributes; - if (attributes.Properties.BlobType == BlobType.BlockBlob) - { - return new CloudBlockBlob(attributes, this.ServiceClient); - } - else if (attributes.Properties.BlobType == BlobType.PageBlob) - { - return new CloudPageBlob(attributes, this.ServiceClient); - } - else - { - throw new InvalidOperationException(SR.InvalidBlobListItem); - } - } - - ListBlobPrefixEntry blobPrefix = protocolItem as ListBlobPrefixEntry; - if (blobPrefix != null) - { - return this.GetDirectoryReference(blobPrefix.Name); - } - - throw new InvalidOperationException(SR.InvalidBlobListItem); - } - - /// - /// Core implementation of the ListBlobs method. - /// - /// The blob prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// Whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A object that specifies additional options for the request. - /// The continuation token. - /// A that lists the blobs. - private RESTCommand> ListBlobsImpl(string prefix, int? maxResults, bool useFlatBlobListing, BlobListingDetails blobListingDetails, BlobRequestOptions options, BlobContinuationToken currentToken) - { - if (!useFlatBlobListing - && (blobListingDetails & BlobListingDetails.Snapshots) == BlobListingDetails.Snapshots) - { - throw new ArgumentException(SR.ListSnapshotsWithDelimiterError, "blobListingDetails"); - } - - string delimiter = useFlatBlobListing ? null : this.ServiceClient.DefaultDelimiter; - BlobListingContext listingContext = new BlobListingContext(prefix, maxResults, delimiter, blobListingDetails) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => ContainerHttpRequestMessageFactory.ListBlobs(cmd.Uri, cmd.ServerTimeoutInSeconds, listingContext, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - ListBlobsResponse listBlobsResponse = new ListBlobsResponse(cmd.ResponseStream); - List blobList = new List( - listBlobsResponse.Blobs.Select(item => this.SelectListBlobItem(item))); - BlobContinuationToken continuationToken = null; - if (listBlobsResponse.NextMarker != null) - { - continuationToken = new BlobContinuationToken() - { - NextMarker = listBlobsResponse.NextMarker, - }; - } - - return new ResultSegment(blobList) - { - ContinuationToken = continuationToken, - }; - }); - }; - - return getCmd; - } - - /// - /// Retrieve ETag and LastModified date time from response. - /// - /// The response to parse. - private void ParseSizeAndLastModified(HttpResponseMessage response) - { - BlobContainerProperties parsedProperties = ContainerHttpResponseParsers.GetProperties(response); - this.Properties.ETag = parsedProperties.ETag; - this.Properties.LastModified = parsedProperties.LastModified; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobDirectory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobDirectory.cs deleted file mode 100644 index 7422aa7a86c49..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobDirectory.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using Windows.Foundation; - - /// - /// Represents a virtual directory of blobs, designated by a delimiter character. - /// - /// Containers, which are encapsulated as objects, hold directories, and directories hold block blobs and page blobs. Directories can also contain sub-directories. - public sealed partial class CloudBlobDirectory - { - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// A token returned by a previous listing operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(BlobContinuationToken currentToken) - { - return this.ListBlobsSegmentedAsync(false, BlobListingDetails.None, null /* maxResults */, currentToken, null /* options */, null /* operationContext */); - } - - /// - /// Returns a result segment containing a collection of blob items - /// in the container. - /// - /// Whether to list blobs in a flat listing, or whether to list blobs hierarchically, by virtual directory. - /// A enumeration describing which items to include in the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A continuation token returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment containing objects that implement . - [DoesServiceRequest] - public IAsyncOperation ListBlobsSegmentedAsync(bool useFlatBlobListing, BlobListingDetails blobListingDetails, int? maxResults, BlobContinuationToken currentToken, BlobRequestOptions options, OperationContext operationContext) - { - return this.Container.ListBlobsSegmentedAsync(this.Prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobSharedImpl.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobSharedImpl.cs deleted file mode 100644 index c9e5aa54b06f3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlobSharedImpl.cs +++ /dev/null @@ -1,556 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.IO; - using System.Net; - using System.Net.Http; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static class CloudBlobSharedImpl - { - /// - /// Implements getting the blob. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that gets the stream. - internal static RESTCommand GetBlobImpl(ICloudBlob blob, BlobAttributes attributes, Stream destStream, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) - { - string lockedETag = null; - AccessCondition lockedAccessCondition = null; - - bool isRangeGet = offset.HasValue; - bool arePropertiesPopulated = false; - string storedMD5 = null; - - long startingOffset = offset.HasValue ? offset.Value : 0; - long? startingLength = length; - long? validateLength = null; - - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.DestinationStream = destStream; - getCmd.CalculateMd5ForResponseStream = !options.DisableContentMD5Validation.Value; - getCmd.Handler = blob.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Get(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value, accessCondition, cnt, ctx); - getCmd.RecoveryAction = (cmd, ex, ctx) => - { - if ((lockedAccessCondition == null) && !string.IsNullOrEmpty(lockedETag)) - { - lockedAccessCondition = AccessCondition.GenerateIfMatchCondition(lockedETag); - if (accessCondition != null) - { - lockedAccessCondition.LeaseId = accessCondition.LeaseId; - } - } - - if (cmd.StreamCopyState != null) - { - offset = startingOffset + cmd.StreamCopyState.Length; - if (startingLength.HasValue) - { - length = startingLength.Value - cmd.StreamCopyState.Length; - } - } - - getCmd.BuildRequest = (command, cnt, context) => BlobHttpRequestMessageFactory.Get(command.Uri, command.ServerTimeoutInSeconds, attributes.SnapshotTime, offset, length, options.UseTransactionalMD5.Value && !arePropertiesPopulated, lockedAccessCondition ?? accessCondition, cnt, context); - }; - - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(offset.HasValue ? HttpStatusCode.PartialContent : HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - if (!arePropertiesPopulated) - { - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, isRangeGet); - - if (resp.Content.Headers.ContentMD5 != null) - { - storedMD5 = Convert.ToBase64String(resp.Content.Headers.ContentMD5); - } - - if (!options.DisableContentMD5Validation.Value && - options.UseTransactionalMD5.Value && - string.IsNullOrEmpty(storedMD5)) - { - throw new StorageException( - cmd.CurrentResult, - SR.MD5NotPresentError, - null) - { - IsRetryable = false - }; - } - - lockedETag = attributes.Properties.ETag; - validateLength = resp.Content.Headers.ContentLength; - - arePropertiesPopulated = true; - } - - return NullType.Value; - }; - - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - HttpResponseParsers.ValidateResponseStreamMd5AndLength(validateLength, storedMD5, cmd); - return Task.FromResult(NullType.Value); - }; - - return getCmd; - } - - /// - /// Implements the FetchAttributes method. The attributes are updated immediately. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that fetches the attributes. - internal static RESTCommand FetchAttributesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = blob.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, accessCondition, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implements the Exists method. The attributes are updated immediately. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that specifies additional options for the request. - /// A that checks existence. - internal static RESTCommand ExistsImpl(ICloudBlob blob, BlobAttributes attributes, BlobRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = blob.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, null /* accessCondition */, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - CloudBlobSharedImpl.UpdateAfterFetchAttributes(attributes, resp, false); - return true; - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that sets the metadata. - internal static RESTCommand SetMetadataImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.SetMetadata(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetProperties method. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that sets the metadata. - internal static RESTCommand SetPropertiesImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.SetProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.Properties, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implements the DeleteBlob method. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that deletes the blob. - internal static RESTCommand DeleteBlobImpl(ICloudBlob blob, BlobAttributes attributes, DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand deleteCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - deleteCmd.ApplyRequestOptions(options); - deleteCmd.Handler = blob.ServiceClient.AuthenticationHandler; - deleteCmd.BuildClient = HttpClientFactory.BuildHttpClient; - deleteCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Delete(cmd.Uri, cmd.ServerTimeoutInSeconds, attributes.SnapshotTime, deleteSnapshotsOption, accessCondition, cnt, ctx); - deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, NullType.Value, cmd, ex); - - return deleteCmd; - } - - /// - /// Generates a for acquiring a lease. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// A representing the span of time for which to acquire the lease, which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A implementing the acquire lease operation. - internal static RESTCommand AcquireLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - int leaseDuration = -1; - if (leaseTime.HasValue) - { - CommonUtility.AssertInBounds("leaseTime", leaseTime.Value, TimeSpan.FromSeconds(1), TimeSpan.MaxValue); - leaseDuration = (int)leaseTime.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Acquire, proposedLeaseId, leaseDuration, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a for renewing a lease. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A implementing the renew lease operation. - internal static RESTCommand RenewLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDRenewing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a for changing a lease ID. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// The proposed new lease ID. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A implementing the change lease ID operation. - internal static RESTCommand ChangeLeaseImpl(ICloudBlob blob, BlobAttributes attributes, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - CommonUtility.AssertNotNull("proposedLeaseId", proposedLeaseId); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDChanging, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Change, proposedLeaseId, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - return BlobHttpResponseParsers.GetLeaseId(resp); - }; - - return putCmd; - } - - /// - /// Generates a for releasing a lease. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A implementing the release lease operation. - internal static RESTCommand ReleaseLeaseImpl(ICloudBlob blob, BlobAttributes attributes, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("accessCondition", accessCondition); - if (accessCondition.LeaseId == null) - { - throw new ArgumentException(SR.MissingLeaseIDReleasing, "accessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Generates a for breaking a lease. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// The amount of time to allow the lease to remain, rounded down to seconds. If null, the break period is the remainder of the current lease, or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A implementing the break lease operation. - internal static RESTCommand BreakLeaseImpl(ICloudBlob blob, BlobAttributes attributes, TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options) - { - int? breakSeconds = null; - if (breakPeriod.HasValue) - { - CommonUtility.AssertInBounds("breakPeriod", breakPeriod.Value, TimeSpan.Zero, TimeSpan.MaxValue); - breakSeconds = (int)breakPeriod.Value.TotalSeconds; - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Lease(cmd.Uri, cmd.ServerTimeoutInSeconds, LeaseAction.Break, null /* proposedLeaseId */, null /* leaseDuration */, breakSeconds, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); - - int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); - if (!remainingLeaseTime.HasValue) - { - // Unexpected result from service. - throw new StorageException(cmd.CurrentResult, SR.LeaseTimeNotReceived, null /* inner */); - } - - return TimeSpan.FromSeconds(remainingLeaseTime.Value); - }; - - return putCmd; - } - - /// - /// Implementation of the StartCopyFromBlob method. Result is a BlobAttributes object derived from the response headers. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// The URI of the source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A delegate for setting the BlobAttributes result. - /// A that starts to copy the blob. - internal static RESTCommand StartCopyFromBlobImpl(ICloudBlob blob, BlobAttributes attributes, Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options) - { - if (sourceAccessCondition != null && !string.IsNullOrEmpty(sourceAccessCondition.LeaseId)) - { - throw new ArgumentException(SR.LeaseConditionOnSource, "sourceAccessCondition"); - } - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.CopyFrom(cmd.Uri, cmd.ServerTimeoutInSeconds, source, sourceAccessCondition, destAccessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, attributes.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex); - CopyState state = BlobHttpResponseParsers.GetCopyAttributes(resp); - attributes.Properties = BlobHttpResponseParsers.GetProperties(resp); - attributes.Metadata = BlobHttpResponseParsers.GetMetadata(resp); - attributes.CopyState = state; - return state.CopyId; - }; - - return putCmd; - } - - /// - /// Implementation of the AbortCopy method. No result is produced. - /// - /// The blob object that is calling this method. - /// The blob's attributes. - /// The copy ID of the copy operation to abort. - /// An object that represents the access conditions for the operation. If null, no condition is used. - /// An object that specifies additional options for the request. - /// A that copies the blob. - internal static RESTCommand AbortCopyImpl(ICloudBlob blob, BlobAttributes attributes, string copyId, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("copyId", copyId); - - RESTCommand putCmd = new RESTCommand(blob.ServiceClient.Credentials, attributes.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = blob.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.AbortCopy(cmd.Uri, cmd.ServerTimeoutInSeconds, copyId, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Updates this blob with the given attributes at the end of a fetch attributes operation. - /// - /// The blob attributes to update. - /// The response to parse. - /// If set to true, do not parse MD5 header. - internal static void UpdateAfterFetchAttributes(BlobAttributes attributes, HttpResponseMessage response, bool ignoreMD5) - { - BlobProperties properties = BlobHttpResponseParsers.GetProperties(response); - - // If BlobType is specified and the value returned from cloud is different, - // then it's a client error and we need to throw. - if (attributes.Properties.BlobType != BlobType.Unspecified && attributes.Properties.BlobType != properties.BlobType) - { - throw new InvalidOperationException(SR.BlobTypeMismatch); - } - - if (ignoreMD5) - { - properties.ContentMD5 = attributes.Properties.ContentMD5; - } - - attributes.Properties = properties; - attributes.Metadata = BlobHttpResponseParsers.GetMetadata(response); - attributes.CopyState = BlobHttpResponseParsers.GetCopyAttributes(response); - } - - /// - /// Retrieve ETag, LMT, and Sequence-Number from response. - /// - /// The blob attributes to update. - /// The response to parse. - internal static void UpdateETagLMTAndSequenceNumber(BlobAttributes attributes, HttpResponseMessage response) - { - BlobProperties parsedProperties = BlobHttpResponseParsers.GetProperties(response); - attributes.Properties.ETag = parsedProperties.ETag ?? attributes.Properties.ETag; - attributes.Properties.LastModified = parsedProperties.LastModified ?? attributes.Properties.LastModified; - attributes.Properties.PageBlobSequenceNumber = parsedProperties.PageBlobSequenceNumber ?? attributes.Properties.PageBlobSequenceNumber; - if (parsedProperties.Length > 0) - { - attributes.Properties.Length = parsedProperties.Length; - } - } - - /// - /// Converts the source blob of a copy operation to an appropriate access URI, taking Shared Access Signature credentials into account. - /// - /// The source blob. - /// A URI addressing the source blob, using SAS if appropriate. - internal static Uri SourceBlobToUri(ICloudBlob source) - { - CommonUtility.AssertNotNull("source", source); - return source.ServiceClient.Credentials.TransformUri(source.SnapshotQualifiedUri); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlockBlob.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlockBlob.cs deleted file mode 100644 index d1d474ab6bbf8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudBlockBlob.cs +++ /dev/null @@ -1,1339 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Text; - using System.Threading.Tasks; - using Windows.Foundation; - using Windows.Foundation.Metadata; - using Windows.Storage; - using Windows.Storage.Streams; - - /// - /// Represents a blob that is uploaded as a set of blocks. - /// - public sealed partial class CloudBlockBlob : ICloudBlob - { - /// - /// Opens a stream for reading from the blob. - /// - /// A stream to be used for reading from the blob. - [DoesServiceRequest] - public IAsyncOperation OpenReadAsync() - { - return this.OpenReadAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - [DoesServiceRequest] - public IAsyncOperation OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - return new BlobReadStreamHelper(this, streamAccessCondition, modifiedOptions, operationContext); - }); - } - - /// - /// Opens a stream for writing to the blob. - /// - /// A stream to be used for writing to the blob. - public IAsyncOperation OpenWriteAsync() - { - return this.OpenWriteAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Opens a stream for writing to the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for writing to the blob. - public IAsyncOperation OpenWriteAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - operationContext = operationContext ?? new OperationContext(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - - if ((accessCondition != null) && accessCondition.IsConditional) - { - return AsyncInfo.Run(async (token) => - { - try - { - await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); - } - catch (Exception) - { - if ((operationContext.LastResult != null) && - (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) && - string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - // If we got a 404 and the condition was not an If-Match, - // we should continue with the operation. - } - else - { - throw; - } - } - - ICloudBlobStream stream = new BlobWriteStreamHelper(this, accessCondition, modifiedOptions, operationContext); - return stream; - }); - } - else - { - ICloudBlobStream stream = new BlobWriteStreamHelper(this, accessCondition, modifiedOptions, operationContext); - return Task.FromResult(stream).AsAsyncOperation(); - } - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source) - { - return this.UploadFromStreamAsyncHelper(source, null /* length*/, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, long length) - { - return this.UploadFromStreamAsyncHelper(source, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsyncHelper(source, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsyncHelper(source, length, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - internal IAsyncAction UploadFromStreamAsyncHelper(IInputStream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - Stream sourceAsStream = source.AsStreamForRead(); - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", length.Value, 1); - - if (sourceAsStream.CanSeek && length > sourceAsStream.Length - sourceAsStream.Position) - { - throw new ArgumentOutOfRangeException("length", SR.StreamLengthShortError); - } - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - return AsyncInfo.Run(async (token) => - { - bool lessThanSingleBlobThreshold = sourceAsStream.CanSeek - && (length ?? sourceAsStream.Length - sourceAsStream.Position) - <= this.ServiceClient.SingleBlobUploadThresholdInBytes; - if (this.ServiceClient.ParallelOperationThreadCount == 1 && lessThanSingleBlobThreshold) - { - string contentMD5 = null; - if (modifiedOptions.StoreBlobContentMD5.Value) - { - StreamDescriptor streamCopyState = new StreamDescriptor(); - long startPosition = sourceAsStream.Position; - await sourceAsStream.WriteToAsync(Stream.Null, length, null /* maxLength */, true, tempExecutionState, streamCopyState, token); - sourceAsStream.Position = startPosition; - contentMD5 = streamCopyState.Md5; - } - else - { - if (modifiedOptions.UseTransactionalMD5.Value) - { - throw new ArgumentException(SR.PutBlobNeedsStoreBlobContentMD5, "options"); - } - } - - await Executor.ExecuteAsyncNullReturn( - this.PutBlobImpl(sourceAsStream, length, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token); - } - else - { - using (ICloudBlobStream blobStream = await this.OpenWriteAsync(accessCondition, options, operationContext).AsTask(token)) - { - // We should always call AsStreamForWrite with bufferSize=0 to prevent buffering. Our - // stream copier only writes 64K buffers at a time anyway, so no buffering is needed. - await sourceAsStream.WriteToAsync(blobStream.AsStreamForWrite(0), length, null /* maxLength */, false, tempExecutionState, null /* streamCopyState */, token); - await blobStream.CommitAsync().AsTask(token); - } - } - }); - } - - /// - /// Uploads a file to the Windows Azure Blob Service. - /// - /// The file providing the blob content. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromFileAsync(StorageFile source) - { - return this.UploadFromFileAsync(source, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a file to a blob. - /// - /// The file providing the blob content. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromFileAsync(StorageFile source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - return AsyncInfo.Run(async (token) => - { - using (IRandomAccessStreamWithContentType stream = await source.OpenReadAsync().AsTask(token)) - { - await this.UploadFromStreamAsync(stream, accessCondition, options, operationContext).AsTask(token); - } - }); - } - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count) - { - return this.UploadFromByteArrayAsync(buffer, index, count, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("buffer", buffer); - - SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count); - return this.UploadFromStreamAsync(stream.AsInputStream(), accessCondition, options, operationContext); - } - - /// - /// Uploads a string of text to a blob. - /// - /// The text to upload, encoded as a UTF-8 string. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadTextAsync(string content) - { - return this.UploadTextAsync(content, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a string of text to a blob. - /// - /// The text to upload, encoded as a UTF-8 string. - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadTextAsync(string content, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("content", content); - - byte[] contentAsBytes = Encoding.UTF8.GetBytes(content); - return this.UploadFromByteArrayAsync(contentAsBytes, 0, contentAsBytes.Length, accessCondition, options, operationContext); - } - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToStreamAsync(IOutputStream target) - { - return this.DownloadToStreamAsync(target, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToStreamAsync(IOutputStream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToStreamAsync(target, null /* offset */, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToFileAsync(StorageFile target) - { - return this.DownloadToFileAsync(target, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToFileAsync(StorageFile target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("target", target); - - return AsyncInfo.Run(async (token) => - { - using (StorageStreamTransaction transaction = await target.OpenTransactedWriteAsync().AsTask(token)) - { - await this.DownloadToStreamAsync(transaction.Stream, accessCondition, options, operationContext).AsTask(token); - await transaction.CommitAsync(); - } - }); - } - - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index) - { - return this.DownloadToByteArrayAsync(target, index, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToByteArrayAsync(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length) - { - return this.DownloadRangeToStreamAsync(target, offset, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the blob's contents as a string. - /// - /// The contents of the blob, as a string. - public IAsyncOperation DownloadTextAsync() - { - return this.DownloadTextAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the blob's contents as a string. - /// - /// An object that represents the access conditions for the blob. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The contents of the blob, as a string. - public IAsyncOperation DownloadTextAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - using (SyncMemoryStream stream = new SyncMemoryStream()) - { - await this.DownloadToStreamAsync(stream.AsOutputStream(), accessCondition, options, operationContext).AsTask(token); - byte[] streamAsBytes = stream.ToArray(); - return Encoding.UTF8.GetString(streamAsBytes, 0, streamAsBytes.Length); - } - }); - } - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - - // We should always call AsStreamForWrite with bufferSize=0 to prevent buffering. Our - // stream copier only writes 64K buffers at a time anyway, so no buffering is needed. - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target.AsStreamForWrite(0), offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - using (SyncMemoryStream stream = new SyncMemoryStream(target, index)) - { - await this.DownloadRangeToStreamAsync(stream.AsOutputStream(), blobOffset, length, accessCondition, options, operationContext).AsTask(token); - return (int)stream.Position; - } - }); - } - - /// - /// Checks existence of the blob. - /// - /// true if the blob exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync() - { - return this.ExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Checks existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Populates a blob's properties and metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync() - { - return this.FetchAttributesAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Updates the blob's metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync() - { - return this.SetMetadataAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Updates the blob's properties. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPropertiesAsync() - { - return this.SetPropertiesAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the blob. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync() - { - return this.DeleteAsync(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the blob if it already exists. - /// - /// true if the blob already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (!exists) - { - return false; - } - - try - { - await this.DeleteAsync(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext).AsTask(token); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Creates a snapshot of the blob. - /// - /// A blob snapshot. - [DoesServiceRequest] - public IAsyncOperation CreateSnapshotAsync() - { - return this.CreateSnapshotAsync(null /* metadata */, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Creates a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// An object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// A blob snapshot. - [DoesServiceRequest] - public IAsyncOperation CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Uploads a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction PutBlockAsync(string blockId, IInputStream blockData, string contentMD5) - { - return this.PutBlockAsync(blockId, blockData, contentMD5, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a single block. - /// - /// A base64-encoded block ID that identifies the block. - /// A stream that provides the data for the block. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction PutBlockAsync(string blockId, IInputStream blockData, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - return AsyncInfo.Run(async (token) => - { - Stream blockDataAsStream = blockData.AsStreamForRead(); - Stream seekableStream = blockDataAsStream; - if (!blockDataAsStream.CanSeek || requiresContentMD5) - { - Stream writeToStream; - if (blockDataAsStream.CanSeek) - { - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - StreamDescriptor streamCopyState = new StreamDescriptor(); - long startPosition = seekableStream.Position; - await blockDataAsStream.WriteToAsync(writeToStream, null /* copyLength */, Constants.MaxBlockSize, requiresContentMD5, tempExecutionState, streamCopyState, token); - seekableStream.Position = startPosition; - - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - } - - await Executor.ExecuteAsyncNullReturn( - this.PutBlockImpl(seekableStream, blockId, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token); - }); - } - - /// - /// Uploads a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction PutBlockListAsync(IEnumerable blockList) - { - return this.PutBlockListAsync(blockList, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a list of blocks to a new or existing blob. - /// - /// An enumerable collection of block IDs, as base64-encoded strings. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction PutBlockListAsync(IEnumerable blockList, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - IEnumerable items = blockList.Select(i => new PutBlockListItem(i, BlockSearchMode.Latest)); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.PutBlockListImpl(items, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Returns an enumerable collection of the committed blocks comprising the blob. - /// - /// An enumerable collection of objects implementing . - [DoesServiceRequest] - public IAsyncOperation> DownloadBlockListAsync() - { - return this.DownloadBlockListAsync(BlockListingFilter.Committed, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Returns an enumerable collection of the blob's blocks, using the specified block list filter. - /// - /// One of the enumeration values that indicates whether to return - /// committed blocks, uncommitted blocks, or both. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of objects implementing . - [DoesServiceRequest] - public IAsyncOperation> DownloadBlockListAsync(BlockListingFilter blockListingFilter, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetBlockListImpl(blockListingFilter, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Requests that the service start to copy an existing blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - [DefaultOverload] - public IAsyncOperation StartCopyFromBlobAsync(Uri source) - { - return this.StartCopyFromBlobAsync(source, null /* sourceAccessCondition */, null /* destAccessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Requests that the service start to copy an existing blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public IAsyncOperation StartCopyFromBlobAsync(CloudBlockBlob source) - { - return this.StartCopyFromBlobAsync(CloudBlobSharedImpl.SourceBlobToUri(source)); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - [DefaultOverload] - public IAsyncOperation StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public IAsyncOperation StartCopyFromBlobAsync(CloudBlockBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext); - } - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction AbortCopyAsync(string copyId) - { - return this.AbortCopyAsync(copyId, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An asynchronous handler called when the operation is complete. - [DoesServiceRequest] - public IAsyncAction AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.BlockBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Implementation for the CreateSnapshot method. - /// - /// A collection of name-value pairs defining the metadata of the snapshot, or null. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the snapshot. - /// If the metadata parameter is null then no metadata is associated with the request. - internal RESTCommand CreateSnapshotImpl(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.Snapshot(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - if (metadata != null) - { - BlobHttpRequestMessageFactory.AddMetadata(msg, metadata); - } - - return msg; - }; - - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp)); - CloudBlockBlob snapshot = new CloudBlockBlob(this.Name, snapshotTime, this.Container); - snapshot.attributes.Metadata = new Dictionary(metadata ?? this.Metadata); - snapshot.attributes.Properties = new BlobProperties(this.Properties); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(snapshot.attributes, resp); - return snapshot; - }; - - return putCmd; - } - - /// - /// Uploads the full blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the stream. - private RESTCommand PutBlobImpl(Stream stream, long? length, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - long offset = stream.Position; - length = length ?? stream.Length - offset; - this.Properties.ContentMD5 = contentMD5; - - CappedLengthReadOnlyStream cappedStream = new CappedLengthReadOnlyStream(stream, length.Value + offset); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(cappedStream, offset, length, null /* md5 */, cmd, ctx); - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.Put(cmd.Uri, cmd.ServerTimeoutInSeconds, this.Properties, BlobType.BlockBlob, 0, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - this.Properties.Length = length.Value; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Uploads the block. - /// - /// The source stream. - /// The block ID. - /// The content MD5. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that uploads the block. - internal RESTCommand PutBlockImpl(Stream source, string blockId, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - long offset = source.Position; - long length = source.Length - offset; - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(source, offset, length, contentMD5, cmd, ctx); - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.PutBlock(cmd.Uri, cmd.ServerTimeoutInSeconds, blockId, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Uploads the block list. - /// - /// The blocks to upload. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that uploads the block list. - internal RESTCommand PutBlockListImpl(IEnumerable blocks, AccessCondition accessCondition, BlobRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - BlobRequest.WriteBlockListBody(blocks, memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - string contentMD5 = memoryStream.ComputeMD5Hash(); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, contentMD5, cmd, ctx); - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.PutBlockList(cmd.Uri, cmd.ServerTimeoutInSeconds, this.Properties, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - this.Properties.Length = -1; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Gets the download block list. - /// - /// The types of blocks. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that gets the download block list. - internal RESTCommand> GetBlockListImpl(BlockListingFilter typesOfBlocks, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.GetBlockList(cmd.Uri, cmd.ServerTimeoutInSeconds, this.SnapshotTime, typesOfBlocks, accessCondition, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return Task.Factory.StartNew(() => - { - GetBlockListResponse responseParser = new GetBlockListResponse(cmd.ResponseStream); - IEnumerable blocks = new List(responseParser.Blocks); - return blocks; - }); - }; - - return getCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudPageBlob.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudPageBlob.cs deleted file mode 100644 index 018e56402f716..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/CloudPageBlob.cs +++ /dev/null @@ -1,1423 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.WindowsAzure.Storage.Blob.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - using Windows.Foundation.Metadata; - using Windows.Storage; - using Windows.Storage.Streams; - - /// - /// Represents a Windows Azure page blob. - /// - public sealed partial class CloudPageBlob : ICloudBlob - { - /// - /// Opens a stream for reading from the blob. - /// - /// A stream to be used for reading from the blob. - [DoesServiceRequest] - public IAsyncOperation OpenReadAsync() - { - return this.OpenReadAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - [DoesServiceRequest] - public IAsyncOperation OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); - AccessCondition streamAccessCondition = AccessCondition.CloneConditionWithETag(accessCondition, this.Properties.ETag); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient, false); - return new BlobReadStreamHelper(this, streamAccessCondition, modifiedOptions, operationContext); - }); - } - - /// - /// Opens a stream for writing to the blob. - /// - /// The size of the write operation, in bytes. The size must be a multiple of 512. - /// A stream to be used for writing to the blob. - [DoesServiceRequest] - public IAsyncOperation OpenWriteAsync(long? size) - { - return this.OpenWriteAsync(size, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Opens a stream for writing to the blob. - /// - /// The size of the write operation, in bytes. The size must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for writing to the blob. - [DoesServiceRequest] - public IAsyncOperation OpenWriteAsync(long? size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - bool createNew = size.HasValue; - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient, false); - if (!createNew && modifiedOptions.StoreBlobContentMD5.Value) - { - throw new ArgumentException(SR.MD5NotPossible); - } - - return AsyncInfo.Run(async (token) => - { - if (createNew) - { - await this.CreateAsync(size.Value, accessCondition, options, operationContext).AsTask(token); - } - else - { - await this.FetchAttributesAsync(accessCondition, options, operationContext).AsTask(token); - size = this.Properties.Length; - } - - if (accessCondition != null) - { - accessCondition = AccessCondition.GenerateLeaseCondition(accessCondition.LeaseId); - } - - ICloudBlobStream stream = new BlobWriteStreamHelper(this, size.Value, createNew, accessCondition, modifiedOptions, operationContext); - return stream; - }); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source) - { - return this.UploadFromStreamAsyncHelper(source, null /* length */, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a stream to a block blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, long length) - { - return this.UploadFromStreamAsyncHelper(source, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsyncHelper(source, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromStreamAsync(IInputStream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.UploadFromStreamAsyncHelper(source, length, accessCondition, options, operationContext); - } - - /// - /// Uploads a stream to a page blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - internal IAsyncAction UploadFromStreamAsyncHelper(IInputStream source, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - Stream sourceAsStream = source.AsStreamForRead(); - - if (!sourceAsStream.CanSeek) - { - throw new InvalidOperationException(); - } - - if (length.HasValue) - { - CommonUtility.AssertInBounds("length", length.Value, 1, sourceAsStream.Length - sourceAsStream.Position); - } - else - { - length = sourceAsStream.Length - sourceAsStream.Position; - } - - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - if ((length % Constants.PageSize) != 0) - { - throw new ArgumentException(SR.InvalidPageSize, "source"); - } - - return AsyncInfo.Run(async (token) => - { - using (ICloudBlobStream blobStream = await this.OpenWriteAsync(length, accessCondition, options, operationContext).AsTask(token)) - { - // We should always call AsStreamForWrite with bufferSize=0 to prevent buffering. Our - // stream copier only writes 64K buffers at a time anyway, so no buffering is needed. - await sourceAsStream.WriteToAsync(blobStream.AsStreamForWrite(0), length, null /* maxLength */, false, tempExecutionState, null /* streamCopyState */, token); - await blobStream.CommitAsync().AsTask(token); - } - }); - } - - /// - /// Uploads a file to the Windows Azure Blob Service. - /// - /// The file providing the blob content. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromFileAsync(StorageFile source) - { - return this.UploadFromFileAsync(source, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads a file to a blob. - /// - /// The file providing the blob content. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromFileAsync(StorageFile source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - - return AsyncInfo.Run(async (token) => - { - using (IRandomAccessStreamWithContentType stream = await source.OpenReadAsync().AsTask(token)) - { - await this.UploadFromStreamAsync(stream, accessCondition, options, operationContext).AsTask(token); - } - }); - } - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count) - { - return this.UploadFromByteArrayAsync(buffer, index, count, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("buffer", buffer); - - SyncMemoryStream stream = new SyncMemoryStream(buffer, index, count); - return this.UploadFromStreamAsync(stream.AsInputStream(), accessCondition, options, operationContext); - } - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToStreamAsync(IOutputStream target) - { - return this.DownloadToStreamAsync(target, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToStreamAsync(IOutputStream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToStreamAsync(target, null /* offset */, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToFileAsync(StorageFile target) - { - return this.DownloadToFileAsync(target, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadToFileAsync(StorageFile target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("target", target); - - return AsyncInfo.Run(async (token) => - { - using (StorageStreamTransaction transaction = await target.OpenTransactedWriteAsync().AsTask(token)) - { - await this.DownloadToStreamAsync(transaction.Stream, accessCondition, options, operationContext).AsTask(token); - await transaction.CommitAsync(); - } - }); - } - - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index) - { - return this.DownloadToByteArrayAsync(target, index, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads the contents of a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.DownloadRangeToByteArrayAsync(target, index, null /* blobOffset */, null /* length */, accessCondition, options, operationContext); - } - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length) - { - return this.DownloadRangeToStreamAsync(target, offset, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The offset at which to begin downloading the blob, in bytes. - /// The length of the data to download from the blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("target", target); - - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - - // We should always call AsStreamForWrite with bufferSize=0 to prevent buffering. Our - // stream copier only writes 64K buffers at a time anyway, so no buffering is needed. - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.GetBlobImpl(this, this.attributes, target.AsStreamForWrite(0), offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length) - { - return this.DownloadRangeToByteArrayAsync(target, index, blobOffset, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - [DoesServiceRequest] - public IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return AsyncInfo.Run(async (token) => - { - using (SyncMemoryStream stream = new SyncMemoryStream(target, index)) - { - await this.DownloadRangeToStreamAsync(stream.AsOutputStream(), blobOffset, length, accessCondition, options, operationContext).AsTask(token); - return (int)stream.Position; - } - }); - } - - /// - /// Creates a page blob. - /// - /// The maximum size of the page blob, in bytes. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync(long size) - { - return this.CreateAsync(size, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Creates a page blob. - /// - /// The maximum size of the page blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.CreateImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Resizes the page blob to the specified size. - /// - /// The maximum size of the page blob, in bytes. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ResizeAsync(long size) - { - return this.ResizeAsync(size, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Resizes the page blob to the specified size. - /// - /// The maximum size of the page blob, in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ResizeAsync(long size, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.ResizeImpl(size, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Sets the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber) - { - return this.SetSequenceNumberAsync(sequenceNumberAction, sequenceNumber, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Sets the page blob's sequence number. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if is equal to . - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetSequenceNumberAsync(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetSequenceNumberImpl(sequenceNumberAction, sequenceNumber, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Checks existence of the blob. - /// - /// true if the blob exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync() - { - return this.ExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Checks existence of the blob. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync(BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.ExistsImpl(this, this.attributes, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Populates a blob's properties and metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync() - { - return this.FetchAttributesAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.FetchAttributesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Gets a collection of valid page ranges and their starting and ending bytes. - /// - /// An enumerable collection of page ranges. - [DoesServiceRequest] - public IAsyncOperation> GetPageRangesAsync() - { - return this.GetPageRangesAsync(null /* offset */, null /* length */, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Gets a collection of valid page ranges and their starting and ending bytes. - /// - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of page ranges. - [DoesServiceRequest] - public IAsyncOperation> GetPageRangesAsync(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetPageRangesImpl(offset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Updates the blob's metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync() - { - return this.SetMetadataAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.SetMetadataImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Updates the blob's properties. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPropertiesAsync() - { - return this.SetPropertiesAsync(null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.SetPropertiesImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the blob. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync() - { - return this.DeleteAsync(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.DeleteBlobImpl(this, this.attributes, deleteSnapshotsOption, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the blob if it already exists. - /// - /// true if the blob already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(DeleteSnapshotsOption.None, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, this.BlobType, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (!exists) - { - return false; - } - - try - { - await this.DeleteAsync(deleteSnapshotsOption, accessCondition, modifiedOptions, operationContext).AsTask(token); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == BlobErrorCodeStrings.BlobNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Creates a snapshot of the blob. - /// - /// A blob snapshot. - [DoesServiceRequest] - public IAsyncOperation CreateSnapshotAsync() - { - return this.CreateSnapshotAsync(null /* metadata */, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Creates a snapshot of the blob. - /// - /// A collection of name-value pairs defining the metadata of the snapshot. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request, or null. - /// An object that represents the context for the current operation. - /// A blob snapshot. - [DoesServiceRequest] - public IAsyncOperation CreateSnapshotAsync(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - this.attributes.AssertNoSnapshot(); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.CreateSnapshotImpl(metadata, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId) - { - return this.AcquireLeaseAsync(leaseTime, proposedLeaseId, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. If null, an infinite lease will be acquired. If not null, this must be - /// greater than zero. - /// A string representing the proposed lease ID for the new lease, or null if no lease ID is proposed. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - [DoesServiceRequest] - public IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.AcquireLeaseImpl(this, this.attributes, leaseTime, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition) - { - return this.RenewLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.RenewLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition) - { - return this.ChangeLeaseAsync(proposedLeaseId, accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. This cannot be null. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// The new lease ID. - [DoesServiceRequest] - public IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.ChangeLeaseImpl(this, this.attributes, proposedLeaseId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition) - { - return this.ReleaseLeaseAsync(accessCondition, null /* options */, null /* operationContext */); - } - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.ReleaseLeaseImpl(this, this.attributes, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod) - { - return this.BreakLeaseAsync(breakPeriod, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. If null, the break period is the remainder of the current lease, - /// or zero for infinite leases. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// The options for this operation. If null, default options will be used. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - [DoesServiceRequest] - public IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.BreakLeaseImpl(this, this.attributes, breakPeriod, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Writes pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction WritePagesAsync(IInputStream pageData, long startOffset, string contentMD5) - { - return this.WritePagesAsync(pageData, startOffset, contentMD5, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Writes pages to a page blob. - /// - /// A stream providing the page data. - /// The offset at which to begin writing, in bytes. The offset must be a multiple of 512. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction WritePagesAsync(IInputStream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - bool requiresContentMD5 = (contentMD5 == null) && modifiedOptions.UseTransactionalMD5.Value; - operationContext = operationContext ?? new OperationContext(); - ExecutionState tempExecutionState = CommonUtility.CreateTemporaryExecutionState(modifiedOptions); - - return AsyncInfo.Run(async (token) => - { - Stream pageDataAsStream = pageData.AsStreamForRead(); - Stream seekableStream = pageDataAsStream; - if (!pageDataAsStream.CanSeek || requiresContentMD5) - { - Stream writeToStream; - if (pageDataAsStream.CanSeek) - { - writeToStream = Stream.Null; - } - else - { - seekableStream = new MultiBufferMemoryStream(this.ServiceClient.BufferManager); - writeToStream = seekableStream; - } - - StreamDescriptor streamCopyState = new StreamDescriptor(); - long startPosition = seekableStream.Position; - await pageDataAsStream.WriteToAsync(writeToStream, null /* copyLength */, Constants.MaxBlockSize, requiresContentMD5, tempExecutionState, streamCopyState, token); - seekableStream.Position = startPosition; - - if (requiresContentMD5) - { - contentMD5 = streamCopyState.Md5; - } - } - - await Executor.ExecuteAsyncNullReturn( - this.PutPageImpl(seekableStream, startOffset, contentMD5, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token); - }); - } - - /// - /// Clears pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ClearPagesAsync(long startOffset, long length) - { - return this.ClearPagesAsync(startOffset, length, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Clears pages from a page blob. - /// - /// The offset at which to begin clearing pages, in bytes. The offset must be a multiple of 512. - /// The length of the data range to be cleared, in bytes. The length must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ClearPagesAsync(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.ClearPageImpl(startOffset, length, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Requests that the service start to copy an existing blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - [DefaultOverload] - public IAsyncOperation StartCopyFromBlobAsync(Uri source) - { - return this.StartCopyFromBlobAsync(source, null /* sourceAccessCondition */, null /* destAccessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Requests that the service start to copy an existing blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public IAsyncOperation StartCopyFromBlobAsync(CloudPageBlob source) - { - return this.StartCopyFromBlobAsync(CloudBlobSharedImpl.SourceBlobToUri(source)); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - [DefaultOverload] - public IAsyncOperation StartCopyFromBlobAsync(Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - CommonUtility.AssertNotNull("source", source); - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - CloudBlobSharedImpl.StartCopyFromBlobImpl(this, this.attributes, source, sourceAccessCondition, destAccessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Requests that the service start to copy a blob's contents, properties, and metadata to a new blob. - /// - /// The URI of a source blob. - /// An object that represents the access conditions for the source blob. If null, no condition is used. - /// An object that represents the access conditions for the destination blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The copy ID associated with the copy operation. - /// - /// This method fetches the blob's ETag, last modified time, and part of the copy state. - /// The copy ID and copy status fields are fetched, and the rest of the copy state is cleared. - /// - [DoesServiceRequest] - public IAsyncOperation StartCopyFromBlobAsync(CloudPageBlob source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, BlobRequestOptions options, OperationContext operationContext) - { - return this.StartCopyFromBlobAsync(CloudBlobSharedImpl.SourceBlobToUri(source), sourceAccessCondition, destAccessCondition, options, operationContext); - } - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction AbortCopyAsync(string copyId) - { - return this.AbortCopyAsync(copyId, null /* accessCondition */, null /* options */, null /* operationContext */); - } - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) - { - BlobRequestOptions modifiedOptions = BlobRequestOptions.ApplyDefaults(options, BlobType.PageBlob, this.ServiceClient); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - CloudBlobSharedImpl.AbortCopyImpl(this, this.attributes, copyId, accessCondition, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Implements the Create method. - /// - /// The size in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the blob. - private RESTCommand CreateImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.Put(cmd.Uri, cmd.ServerTimeoutInSeconds, this.Properties, BlobType.PageBlob, sizeInBytes, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Resize method. - /// - /// The size in bytes. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand ResizeImpl(long sizeInBytes, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.Resize(cmd.Uri, cmd.ServerTimeoutInSeconds, sizeInBytes, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - this.Properties.Length = sizeInBytes; - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetSequenceNumber method. - /// - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if this operation is an increment action. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand SetSequenceNumberImpl(SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.SetSequenceNumber(cmd.Uri, cmd.ServerTimeoutInSeconds, sequenceNumberAction, sequenceNumber, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the CreateSnapshot method. - /// - /// A collection of name-value pairs defining the metadata of the snapshot, or null. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that creates the snapshot. - /// If the metadata parameter is null then no metadata is associated with the request. - private RESTCommand CreateSnapshotImpl(IDictionary metadata, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.Snapshot(cmd.Uri, cmd.ServerTimeoutInSeconds, accessCondition, cnt, ctx); - if (metadata != null) - { - BlobHttpRequestMessageFactory.AddMetadata(msg, metadata); - } - - return msg; - }; - - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); - DateTimeOffset snapshotTime = NavigationHelper.ParseSnapshotTime(BlobHttpResponseParsers.GetSnapshotTime(resp)); - CloudPageBlob snapshot = new CloudPageBlob(this.Name, snapshotTime, this.Container); - snapshot.attributes.Metadata = new Dictionary(metadata ?? this.Metadata); - snapshot.attributes.Properties = new BlobProperties(this.Properties); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(snapshot.attributes, resp); - return snapshot; - }; - - return putCmd; - } - - /// - /// Implementation for get page ranges. - /// - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A for getting the page ranges. - private RESTCommand> GetPageRangesImpl(long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = BlobHttpRequestMessageFactory.GetPageRanges(cmd.Uri, cmd.ServerTimeoutInSeconds, this.SnapshotTime, offset, length, accessCondition, cnt, ctx); - BlobHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return Task.Factory.StartNew(() => - { - GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(cmd.ResponseStream); - IEnumerable pageRanges = new List(getPageRangesResponse.PageRanges); - return pageRanges; - }); - }; - - return getCmd; - } - - /// - /// Implementation method for the WritePage methods. - /// - /// The page data. - /// The start offset. - /// An optional hash value that will be used to set the property - /// on the blob. May be null or an empty string. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that writes the pages. - private RESTCommand PutPageImpl(Stream pageData, long startOffset, string contentMD5, AccessCondition accessCondition, BlobRequestOptions options) - { - if (startOffset % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("startOffset", startOffset); - } - - long offset = pageData.Position; - long length = pageData.Length - offset; - - PageRange pageRange = new PageRange(startOffset, startOffset + length - 1); - PageWrite pageWrite = PageWrite.Update; - - if ((1 + pageRange.EndOffset - pageRange.StartOffset) % Constants.PageSize != 0 || - (1 + pageRange.EndOffset - pageRange.StartOffset) == 0) - { - CommonUtility.ArgumentOutOfRange("pageData", pageData); - } - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(pageData, offset, length, contentMD5, cmd, ctx); - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.PutPage(cmd.Uri, cmd.ServerTimeoutInSeconds, pageRange, pageWrite, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation method for the ClearPage methods. - /// - /// The start offset. Must be multiples of 512. - /// Length of the data range to be cleared. Must be multiples of 512. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// A that writes the pages. - private RESTCommand ClearPageImpl(long startOffset, long length, AccessCondition accessCondition, BlobRequestOptions options) - { - CommonUtility.AssertNotNull("options", options); - - if (startOffset < 0 || startOffset % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("startOffset", startOffset); - } - - if (length <= 0 || length % Constants.PageSize != 0) - { - CommonUtility.ArgumentOutOfRange("length", length); - } - - PageRange pageRange = new PageRange(startOffset, startOffset + length - 1); - PageWrite pageWrite = PageWrite.Clear; - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => BlobHttpRequestMessageFactory.PutPage(cmd.Uri, cmd.ServerTimeoutInSeconds, pageRange, pageWrite, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(this.attributes, resp); - return NullType.Value; - }; - - return putCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlob.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlob.cs deleted file mode 100644 index ee0c8c39ddcea..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlob.cs +++ /dev/null @@ -1,408 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System; - using System.Runtime.InteropServices.WindowsRuntime; - using Windows.Foundation; - using Windows.Storage; - using Windows.Storage.Streams; - - /// - /// An interface required for Windows Azure blob types. The and classes implement the interface. - /// - public partial interface ICloudBlob : IListBlobItem, IRandomAccessStreamReference - { - /// - /// Opens a stream for reading from the blob. - /// - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A stream to be used for reading from the blob. - IAsyncOperation OpenReadAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Uploads a stream to the Windows Azure Blob Service. - /// - /// The stream providing the blob content. - /// An that represents an asynchronous action. - IAsyncAction UploadFromStreamAsync(IInputStream source); - - /// - /// Uploads a stream to a blob. - /// - /// The stream providing the blob content. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction UploadFromStreamAsync(IInputStream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Uploads a stream to a blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An that represents an asynchronous action. - IAsyncAction UploadFromStreamAsync(IInputStream source, long length); - - /// - /// Uploads a stream to a blob. - /// - /// The stream providing the blob content. - /// The number of bytes to write from the source stream at its current position. - /// An object that represents the access conditions for the blob. If null, no condition is used. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction UploadFromStreamAsync(IInputStream source, long length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// Uploads a file to the Windows Azure Blob Service. - /// - /// The file providing the blob content. - /// An that represents an asynchronous action. - IAsyncAction UploadFromFileAsync(StorageFile source); - - /// - /// Uploads a file to a blob. - /// - /// The file providing the blob content. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction UploadFromFileAsync(StorageFile source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An that represents an asynchronous action. - IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count); - - /// - /// Uploads the contents of a byte array to a blob. - /// - /// An array of bytes. - /// The zero-based byte offset in buffer at which to begin uploading bytes to the blob. - /// The number of bytes to be written to the blob. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction UploadFromByteArrayAsync([ReadOnlyArray] byte[] buffer, int index, int count, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An that represents an asynchronous action. - IAsyncAction DownloadToStreamAsync(IOutputStream target); - - /// - /// Downloads the contents of a blob to a stream. - /// - /// The target stream. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction DownloadToStreamAsync(IOutputStream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An that represents an asynchronous action. - IAsyncAction DownloadToFileAsync(StorageFile target); - - /// - /// Downloads the contents of a blob to a file. - /// - /// The target file. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction DownloadToFileAsync(StorageFile target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The total number of bytes read into the buffer. - IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index); - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - IAsyncOperation DownloadToByteArrayAsync([WriteOnlyArray] byte[] target, int index, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An that represents an asynchronous action. - IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length); - - /// - /// Downloads a range of bytes from a blob to a stream. - /// - /// The target stream. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction DownloadRangeToStreamAsync(IOutputStream target, long? offset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// The total number of bytes read into the buffer. - IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length); - - /// - /// Downloads a range of bytes from a blob to a byte array. - /// - /// The target byte array. - /// The starting offset in the byte array. - /// The starting offset of the data range, in bytes. - /// The length of the data range, in bytes. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The total number of bytes read into the buffer. - IAsyncOperation DownloadRangeToByteArrayAsync([WriteOnlyArray] byte[] target, int index, long? blobOffset, long? length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Checks whether the blob exists. - /// - /// true if the blob exists. - IAsyncOperation ExistsAsync(); - - /// - /// Checks whether the blob exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob exists. - IAsyncOperation ExistsAsync(BlobRequestOptions options, OperationContext operationContext); - - /// - /// Populates a blob's properties and metadata. - /// - /// An that represents an asynchronous action. - IAsyncAction FetchAttributesAsync(); - - /// - /// Populates a blob's properties and metadata. - /// - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction FetchAttributesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Updates the blob's metadata. - /// - /// An that represents an asynchronous action. - IAsyncAction SetMetadataAsync(); - - /// - /// Updates the blob's metadata. - /// - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction SetMetadataAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Updates the blob's properties. - /// - /// An that represents an asynchronous action. - IAsyncAction SetPropertiesAsync(); - - /// - /// Updates the blob's properties. - /// - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction SetPropertiesAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Deletes the blob. - /// - /// An that represents an asynchronous action. - IAsyncAction DeleteAsync(); - - /// - /// Deletes the blob. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction DeleteAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Deletes the blob if it already exists. - /// - /// true if the blob did not already exist and was created; otherwise false. - IAsyncOperation DeleteIfExistsAsync(); - - /// - /// Deletes the blob if it already exists. - /// - /// Whether to only delete the blob, to delete the blob and all snapshots, or to only delete the snapshots. - /// An object that represents the access conditions for the container. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the blob did not already exist and was created; otherwise false. - IAsyncOperation DeleteIfExistsAsync(DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// The ID of the acquired lease. - IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId); - - /// - /// Acquires a lease on this blob. - /// - /// A representing the span of time for which to acquire the lease, - /// which will be rounded down to seconds. - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The ID of the acquired lease. - IAsyncOperation AcquireLeaseAsync(TimeSpan? leaseTime, string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - IAsyncAction RenewLeaseAsync(AccessCondition accessCondition); - - /// - /// Renews a lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction RenewLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// The new lease ID. - IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition); - - /// - /// Changes the lease ID on this blob. - /// - /// A string representing the proposed lease ID for the new lease. - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The new lease ID. - IAsyncOperation ChangeLeaseAsync(string proposedLeaseId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// An that represents an asynchronous action. - IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition); - - /// - /// Releases the lease on this blob. - /// - /// An object that represents the access conditions for the blob, including a required lease ID. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction ReleaseLeaseAsync(AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// A representing the amount of time before the lease ends, to the second. - IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod); - - /// - /// Breaks the current lease on this blob. - /// - /// A representing the amount of time to allow the lease to remain, - /// which will be rounded down to seconds. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A representing the amount of time before the lease ends, to the second. - IAsyncOperation BreakLeaseAsync(TimeSpan? breakPeriod, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An that represents an asynchronous action. - IAsyncAction AbortCopyAsync(string copyId); - - /// - /// Aborts an ongoing blob copy operation. - /// - /// A string identifying the copy operation. - /// An object that represents the access conditions for the blob. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - IAsyncAction AbortCopyAsync(string copyId, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlobStream.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlobStream.cs deleted file mode 100644 index b72a2748f9bf8..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/ICloudBlobStream.cs +++ /dev/null @@ -1,31 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Windows.Foundation; - using Windows.Storage.Streams; - - public interface ICloudBlobStream : IRandomAccessStream - { - /// - /// Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying blob, and commits the blob. - /// - /// An that represents an asynchronous action. - IAsyncAction CommitAsync(); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpRequestMessageFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpRequestMessageFactory.cs deleted file mode 100644 index dca54c8e32984..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpRequestMessageFactory.cs +++ /dev/null @@ -1,662 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Net.Http; - using System.Net.Http.Headers; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static class BlobHttpRequestMessageFactory - { - /// - /// Constructs a web request to create a new block blob or page blob, or to update the content - /// of an existing block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The properties to set for the blob. - /// The type of the blob. - /// For a page blob, the size of the blob. This parameter is ignored - /// for block blobs. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Put(Uri uri, int? timeout, BlobProperties properties, BlobType blobType, long pageBlobSize, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - if (blobType == BlobType.Unspecified) - { - throw new InvalidOperationException(SR.UndefinedBlobType); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, null /* builder */, content, operationContext); - - if (properties.CacheControl != null) - { - request.Headers.CacheControl = CacheControlHeaderValue.Parse(properties.CacheControl); - } - - if (content != null) - { - if (properties.ContentType != null) - { - content.Headers.ContentType = MediaTypeHeaderValue.Parse(properties.ContentType); - } - - if (properties.ContentMD5 != null) - { - content.Headers.ContentMD5 = Convert.FromBase64String(properties.ContentMD5); - } - - if (properties.ContentLanguage != null) - { - content.Headers.ContentLanguage.Add(properties.ContentLanguage); - } - - if (properties.ContentEncoding != null) - { - content.Headers.ContentEncoding.Add(properties.ContentEncoding); - } - } - - if (blobType == BlobType.PageBlob) - { - request.Headers.Add(Constants.HeaderConstants.BlobType, Constants.HeaderConstants.PageBlob); - request.Headers.Add(Constants.HeaderConstants.BlobContentLengthHeader, pageBlobSize.ToString(NumberFormatInfo.InvariantInfo)); - properties.Length = pageBlobSize; - } - else - { - request.Headers.Add(Constants.HeaderConstants.BlobType, Constants.HeaderConstants.BlockBlob); - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds the snapshot. - /// - /// The builder. - /// The snapshot version, if the blob is a snapshot. - private static void AddSnapshot(UriQueryBuilder builder, DateTimeOffset? snapshot) - { - if (snapshot.HasValue) - { - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(snapshot.Value)); - } - } - - /// - /// Constructs a web request to return the list of valid page ranges for a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The starting offset of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The length of the data range over which to list page ranges, in bytes. Must be a multiple of 512. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetPageRanges(Uri uri, int? timeout, DateTimeOffset? snapshot, long? offset, long? count, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - if (offset.HasValue) - { - CommonUtility.AssertNotNull("count", count); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "pagelist"); - BlobHttpRequestMessageFactory.AddSnapshot(builder, snapshot); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - AddRange(request, offset, count); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds the Range Header for Blob Service Operations. - /// - /// Request - /// Starting byte of the range - /// Number of bytes in the range - private static void AddRange(HttpRequestMessage request, long? offset, long? count) - { - if (count.HasValue) - { - CommonUtility.AssertNotNull("offset", offset); - CommonUtility.AssertInBounds("count", count.Value, 1, long.MaxValue); - } - - if (offset.HasValue) - { - string rangeStart = offset.ToString(); - string rangeEnd = string.Empty; - if (count.HasValue) - { - rangeEnd = (offset + count.Value - 1).ToString(); - } - - string rangeHeaderValue = string.Format(CultureInfo.InvariantCulture, Constants.HeaderConstants.RangeHeaderFormat, rangeStart, rangeEnd); - request.Headers.Add(Constants.HeaderConstants.RangeHeader, rangeHeaderValue); - } - } - - /// - /// Constructs a web request to return the blob's system properties. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The access condition to apply to the request. - /// A web request for performing the operation. - public static HttpRequestMessage GetProperties(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpRequestMessageFactory.AddSnapshot(builder, snapshot); - - HttpRequestMessage request = HttpRequestMessageFactory.GetProperties(uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set system properties for a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The blob's properties. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetProperties(Uri uri, int? timeout, BlobProperties properties, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.AddOptionalHeader(Constants.HeaderConstants.CacheControlHeader, properties.CacheControl); - request.AddOptionalHeader(Constants.HeaderConstants.ContentEncodingHeader, properties.ContentEncoding); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentLanguageHeader, properties.ContentLanguage); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentMD5Header, properties.ContentMD5); - request.AddOptionalHeader(Constants.HeaderConstants.ContentTypeHeader, properties.ContentType); - - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Constructs a web request to resize a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The new blob size, if the blob is a page blob. Set this parameter to null to keep the existing blob size. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Resize(Uri uri, int? timeout, long newBlobSize, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.Headers.Add(Constants.HeaderConstants.BlobContentLengthHeader, newBlobSize.ToString(NumberFormatInfo.InvariantInfo)); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set a page blob's sequence number. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// A value of type , indicating the operation to perform on the sequence number. - /// The sequence number. Set this parameter to null if this operation is an increment action. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetSequenceNumber(Uri uri, int? timeout, SequenceNumberAction sequenceNumberAction, long? sequenceNumber, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - CommonUtility.AssertInBounds("sequenceNumberAction", sequenceNumberAction, SequenceNumberAction.Max, SequenceNumberAction.Increment); - if (sequenceNumberAction == SequenceNumberAction.Increment) - { - if (sequenceNumber.HasValue) - { - throw new ArgumentException(SR.BlobInvalidSequenceNumber, "sequenceNumber"); - } - } - else - { - CommonUtility.AssertNotNull("sequenceNumber", sequenceNumber); - CommonUtility.AssertInBounds("sequenceNumber", sequenceNumber.Value, 0); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.Headers.Add(Constants.HeaderConstants.SequenceNumberAction, sequenceNumberAction.ToString()); - if (sequenceNumberAction != SequenceNumberAction.Increment) - { - request.Headers.Add(Constants.HeaderConstants.BlobSequenceNumber, sequenceNumber.Value.ToString()); - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to return the user-defined metadata for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The access condition to apply to the request. - /// A web request for performing the operation. - public static HttpRequestMessage GetMetadata(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpRequestMessageFactory.AddSnapshot(builder, snapshot); - - HttpRequestMessage request = HttpRequestMessageFactory.GetMetadata(uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set user-defined metadata for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request for performing the operation. - public static HttpRequestMessage SetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetMetadata(uri, timeout, null /* builder */, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpRequestMessage request, IDictionary metadata) - { - HttpRequestMessageFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpRequestMessage request, string name, string value) - { - HttpRequestMessageFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to delete a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// A set of options indicating whether to delete only blobs, only snapshots, or both. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Delete(Uri uri, int? timeout, DateTimeOffset? snapshot, DeleteSnapshotsOption deleteSnapshotsOption, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - if ((snapshot != null) && (deleteSnapshotsOption != DeleteSnapshotsOption.None)) - { - throw new InvalidOperationException(string.Format(SR.DeleteSnapshotsNotValidError, "deleteSnapshotsOption", "snapshot")); - } - - UriQueryBuilder builder = new UriQueryBuilder(); - BlobHttpRequestMessageFactory.AddSnapshot(builder, snapshot); - - HttpRequestMessage request = HttpRequestMessageFactory.Delete(uri, timeout, builder, content, operationContext); - - switch (deleteSnapshotsOption) - { - case DeleteSnapshotsOption.None: - break; // nop - - case DeleteSnapshotsOption.IncludeSnapshots: - request.Headers.Add( - Constants.HeaderConstants.DeleteSnapshotHeader, - Constants.HeaderConstants.IncludeSnapshotsValue); - break; - - case DeleteSnapshotsOption.DeleteSnapshotsOnly: - request.Headers.Add( - Constants.HeaderConstants.DeleteSnapshotHeader, - Constants.HeaderConstants.SnapshotsOnlyValue); - break; - } - - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Constructs a web request to create a snapshot of a blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Snapshot(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "snapshot"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to use to acquire, renew, change, release or break the lease for the blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval, in seconds. - /// The lease action to perform. - /// A lease ID to propose for the result of an acquire or change operation, - /// or null if no ID is proposed for an acquire operation. This should be null for renew, release, and break operations. - /// The lease duration, in seconds, for acquire operations. - /// If this is -1 then an infinite duration is specified. This should be null for renew, change, release, and break operations. - /// The amount of time to wait, in seconds, after a break operation before the lease is broken. - /// If this is null then the default time is used. This should be null for acquire, renew, change, and release operations. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Lease(Uri uri, int? timeout, LeaseAction action, string proposedLeaseId, int? leaseDuration, int? leaseBreakPeriod, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "lease"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - - // Add lease headers - BlobHttpRequestMessageFactory.AddLeaseAction(request, action); - BlobHttpRequestMessageFactory.AddLeaseDuration(request, leaseDuration); - BlobHttpRequestMessageFactory.AddProposedLeaseId(request, proposedLeaseId); - BlobHttpRequestMessageFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod); - - return request; - } - - /// - /// Adds a proposed lease id to a request. - /// - /// The request. - /// The proposed lease id. - internal static void AddProposedLeaseId(HttpRequestMessage request, string proposedLeaseId) - { - request.AddOptionalHeader(Constants.HeaderConstants.ProposedLeaseIdHeader, proposedLeaseId); - } - - /// - /// Adds a lease duration to a request. - /// - /// The request. - /// The lease duration. - internal static void AddLeaseDuration(HttpRequestMessage request, int? leaseDuration) - { - request.AddOptionalHeader(Constants.HeaderConstants.LeaseDurationHeader, leaseDuration); - } - - /// - /// Adds a lease break period to a request. - /// - /// The request. - /// The lease break period. - internal static void AddLeaseBreakPeriod(HttpRequestMessage request, int? leaseBreakPeriod) - { - request.AddOptionalHeader(Constants.HeaderConstants.LeaseBreakPeriodHeader, leaseBreakPeriod); - } - - /// - /// Adds a lease action to a request. - /// - /// The request. - /// The lease action. - internal static void AddLeaseAction(HttpRequestMessage request, LeaseAction leaseAction) - { - request.Headers.Add(Constants.HeaderConstants.LeaseActionHeader, leaseAction.ToString().ToLower()); - } - - /// - /// Constructs a web request to write a block to a block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The block ID for this block. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage PutBlock(Uri uri, int? timeout, string blockId, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "block"); - builder.Add("blockid", blockId); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - request.ApplyLeaseId(accessCondition); - return request; - } - - /// - /// Constructs a web request to create or update a blob by committing a block list. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The properties to set for the blob. - /// The access condition to apply to the request. - /// A web request for performing the operation. - public static HttpRequestMessage PutBlockList(Uri uri, int? timeout, BlobProperties properties, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "blocklist"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.AddOptionalHeader(Constants.HeaderConstants.CacheControlHeader, properties.CacheControl); - request.AddOptionalHeader(Constants.HeaderConstants.ContentTypeHeader, properties.ContentType); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentMD5Header, properties.ContentMD5); - request.AddOptionalHeader(Constants.HeaderConstants.BlobContentLanguageHeader, properties.ContentLanguage); - request.AddOptionalHeader(Constants.HeaderConstants.ContentEncodingHeader, properties.ContentEncoding); - - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Constructs a web request to return the list of blocks for a block blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot timestamp, if the blob is a snapshot. - /// The types of blocks to include in the list: committed, uncommitted, or both. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetBlockList(Uri uri, int? timeout, DateTimeOffset? snapshot, BlockListingFilter typesOfBlocks, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "blocklist"); - builder.Add("blocklisttype", typesOfBlocks.ToString()); - BlobHttpRequestMessageFactory.AddSnapshot(builder, snapshot); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to write or clear a range of pages in a page blob. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The blob's properties. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage PutPage(Uri uri, int? timeout, PageRange pageRange, PageWrite pageWrite, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "page"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.Headers.Add(Constants.HeaderConstants.RangeHeader, pageRange.ToString()); - request.Headers.Add(Constants.HeaderConstants.PageWrite, pageWrite.ToString()); - - request.ApplyAccessCondition(accessCondition); - request.ApplySequenceNumberCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to copy a blob. - /// - /// The absolute URI to the destination blob. - /// The server timeout interval. - /// The absolute URI to the source blob, including any necessary authentication parameters. - /// The access condition to apply to the source blob. - /// The access condition to apply to the destination blob. - /// A web request to use to perform the operation. - public static HttpRequestMessage CopyFrom(Uri uri, int? timeout, Uri source, AccessCondition sourceAccessCondition, AccessCondition destAccessCondition, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, null /* builder */, content, operationContext); - - request.Headers.Add(Constants.HeaderConstants.CopySourceHeader, source.AbsoluteUri); - request.ApplyAccessCondition(destAccessCondition); - request.ApplyAccessConditionToSource(sourceAccessCondition); - - return request; - } - - /// - /// Generates a web request to abort a copy operation. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The ID string of the copy operation to be aborted. - /// The access condition to apply to the request. - /// Only lease conditions are supported for this operation. - /// A web request for performing the operation. - public static HttpRequestMessage AbortCopy(Uri uri, int? timeout, string copyId, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "copy"); - builder.Add(Constants.QueryConstants.CopyId, copyId); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - request.Headers.Add(Constants.HeaderConstants.CopyActionHeader, Constants.HeaderConstants.CopyActionAbort); - request.ApplyAccessCondition(accessCondition); - - return request; - } - - /// - /// Constructs a web request to get the blob's content, properties, and metadata. - /// - /// The absolute URI to the blob. - /// The server timeout interval. - /// The snapshot version, if the blob is a snapshot. - /// The access condition to apply to the request. - /// A web request for performing the operation. - public static HttpRequestMessage Get(Uri uri, int? timeout, DateTimeOffset? snapshot, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - if (snapshot.HasValue) - { - builder.Add("snapshot", BlobRequest.ConvertDateTimeToSnapshotString(snapshot.Value)); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to return a specified range of the blob's content, together with its properties and metadata. - /// - /// The absolute URI to the blob. - /// The server timeout interval, in seconds. - /// The snapshot version, if the blob is a snapshot. - /// The byte offset at which to begin returning content. - /// The number of bytes to return, or null to return all bytes through the end of the blob. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Get(Uri uri, int? timeout, DateTimeOffset? snapshot, long? offset, long? count, bool rangeContentMD5, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - if (offset.HasValue && offset.Value < 0) - { - CommonUtility.ArgumentOutOfRange("offset", offset); - } - - if (offset.HasValue && rangeContentMD5) - { - CommonUtility.AssertNotNull("count", count); - CommonUtility.AssertInBounds("count", count.Value, 1, Constants.MaxBlockSize); - } - - HttpRequestMessage request = Get(uri, timeout, snapshot, accessCondition, content, operationContext); - AddRange(request, offset, count); - - if (offset.HasValue && rangeContentMD5) - { - request.Headers.Add(Constants.HeaderConstants.RangeContentMD5Header, Constants.HeaderConstants.TrueHeader); - } - - return request; - } - - /// - /// Constructs a web request to get the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A HttpRequestMessage to get the service properties. - public static HttpRequestMessage GetServiceProperties(Uri uri, int? timeout, OperationContext operationContext) - { - return HttpRequestMessageFactory.GetServiceProperties(uri, timeout, operationContext); - } - - /// - /// Creates a web request to set the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A web request to set the service properties. - internal static HttpRequestMessage SetServiceProperties(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - return HttpRequestMessageFactory.SetServiceProperties(uri, timeout, content, operationContext); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpResponseParsers.cs deleted file mode 100644 index a7242655c5fa0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/BlobHttpResponseParsers.cs +++ /dev/null @@ -1,216 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net.Http; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static partial class BlobHttpResponseParsers - { - /// - /// Gets the blob's properties from the response. - /// - /// The web response. - /// The blob's properties. - public static BlobProperties GetProperties(HttpResponseMessage response) - { - BlobProperties properties = new BlobProperties(); - - if (response.Content != null) - { - properties.LastModified = response.Content.Headers.LastModified; - properties.ContentEncoding = HttpWebUtility.CombineHttpHeaderValues(response.Content.Headers.ContentEncoding); - properties.ContentLanguage = HttpWebUtility.CombineHttpHeaderValues(response.Content.Headers.ContentLanguage); - - if (response.Content.Headers.ContentMD5 != null) - { - properties.ContentMD5 = Convert.ToBase64String(response.Content.Headers.ContentMD5); - } - - if (response.Content.Headers.ContentType != null) - { - properties.ContentType = response.Content.Headers.ContentType.ToString(); - } - - // Get the content length. Prioritize range and x-ms over content length for the special cases. - string contentLengthHeader = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobContentLengthHeader); - if ((response.Content.Headers.ContentRange != null) && - response.Content.Headers.ContentRange.HasLength) - { - properties.Length = response.Content.Headers.ContentRange.Length.Value; - } - else if (!string.IsNullOrEmpty(contentLengthHeader)) - { - properties.Length = long.Parse(contentLengthHeader); - } - else if (response.Content.Headers.ContentLength.HasValue) - { - properties.Length = response.Content.Headers.ContentLength.Value; - } - } - - if (response.Headers.CacheControl != null) - { - properties.CacheControl = response.Headers.CacheControl.ToString(); - } - - if (response.Headers.ETag != null) - { - properties.ETag = response.Headers.ETag.ToString(); - } - - // Get blob type - string blobType = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobType); - if (!string.IsNullOrEmpty(blobType)) - { - properties.BlobType = (BlobType)Enum.Parse(typeof(BlobType), blobType, true); - } - - // Get lease properties - properties.LeaseStatus = GetLeaseStatus(response); - properties.LeaseState = GetLeaseState(response); - properties.LeaseDuration = GetLeaseDuration(response); - - // Get sequence number - string sequenceNumber = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobSequenceNumber); - if (!string.IsNullOrEmpty(sequenceNumber)) - { - properties.PageBlobSequenceNumber = long.Parse(sequenceNumber); - } - - return properties; - } - - /// - /// Extracts the lease status from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseStatus GetLeaseStatus(HttpResponseMessage response) - { - string leaseStatus = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseStatus); - return GetLeaseStatus(leaseStatus); - } - - /// - /// Extracts the lease state from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseState GetLeaseState(HttpResponseMessage response) - { - string leaseState = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseState); - return GetLeaseState(leaseState); - } - - /// - /// Extracts the lease duration from a web response. - /// - /// The web response. - /// A enumeration from the web response. - /// If the appropriate header is not present, a status of is returned. - /// The header contains an unrecognized value. - public static LeaseDuration GetLeaseDuration(HttpResponseMessage response) - { - string leaseDuration = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseDurationHeader); - return GetLeaseDuration(leaseDuration); - } - - /// - /// Extracts the lease ID header from a web response. - /// - /// The web response. - /// The lease ID. - public static string GetLeaseId(HttpResponseMessage response) - { - return response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseIdHeader); - } - - /// - /// Extracts the remaining lease time from a web response. - /// - /// The web response. - /// The remaining lease time, in seconds. - public static int? GetRemainingLeaseTime(HttpResponseMessage response) - { - string leaseTime = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseTimeHeader); - int remainingLeaseTime; - if (int.TryParse(leaseTime, out remainingLeaseTime)) - { - return remainingLeaseTime; - } - else - { - return null; - } - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - public static IDictionary GetMetadata(HttpResponseMessage response) - { - return HttpResponseParsers.GetMetadata(response); - } - - /// - /// Extracts a object from the headers of a web response. - /// - /// The HTTP web response. - /// A object, or null if the web response does not contain a copy status. - public static CopyState GetCopyAttributes(HttpResponseMessage response) - { - string copyStatusString = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopyStatusHeader); - if (!string.IsNullOrEmpty(copyStatusString)) - { - return GetCopyAttributes( - copyStatusString, - response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopyIdHeader), - response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopySourceHeader), - response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopyProgressHeader), - response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopyCompletionTimeHeader), - response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.CopyDescriptionHeader)); - } - else - { - return null; - } - } - - /// - /// Gets the snapshot timestamp from the response. - /// - /// The web response. - /// The snapshot timestamp. - public static string GetSnapshotTime(HttpResponseMessage response) - { - return response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.SnapshotHeader); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpRequestMessageFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpRequestMessageFactory.cs deleted file mode 100644 index 83b7a8bc3b412..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpRequestMessageFactory.cs +++ /dev/null @@ -1,363 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net.Http; - using System.Text; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static class ContainerHttpRequestMessageFactory - { - /// - /// Constructs a web request to create a new container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage Create(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - return ContainerHttpRequestMessageFactory.Create(uri, timeout, content, operationContext, BlobContainerPublicAccessType.Off); - } - - /// - /// Constructs a web request to create a new container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// An object that specifies whether data in the container may be accessed publicly and what level of access is to be allowed. - /// A web request to use to perform the operation. - public static HttpRequestMessage Create(Uri uri, int? timeout, HttpContent content, OperationContext operationContext, BlobContainerPublicAccessType accessType) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpRequestMessage request = HttpRequestMessageFactory.Create(uri, timeout, containerBuilder, content, operationContext); - - if (accessType != BlobContainerPublicAccessType.Off) - { - request.Headers.Add(Constants.HeaderConstants.ContainerPublicAccessType, accessType.ToString().ToLower()); - } - - return request; - } - - /// - /// Constructs a web request to delete the container and all of the blobs within it. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Delete(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpRequestMessage request = HttpRequestMessageFactory.Delete(uri, timeout, containerBuilder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return the user-defined metadata for this container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpRequestMessage request = HttpRequestMessageFactory.GetMetadata(uri, timeout, containerBuilder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return the properties and user-defined metadata for this container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetProperties(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpRequestMessage request = HttpRequestMessageFactory.GetProperties(uri, timeout, containerBuilder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to set user-defined metadata for the container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetMetadata(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder containerBuilder = GetContainerUriQueryBuilder(); - HttpRequestMessage request = HttpRequestMessageFactory.SetMetadata(uri, timeout, containerBuilder, content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to use to acquire, renew, change, release or break the lease for the container. - /// - /// The absolute URI to the container. - /// The server timeout interval, in seconds. - /// The lease action to perform. - /// A lease ID to propose for the result of an acquire or change operation, - /// or null if no ID is proposed for an acquire operation. This should be null for renew, release, and break operations. - /// The lease duration, in seconds, for acquire operations. - /// If this is -1 then an infinite duration is specified. This should be null for renew, change, release, and break operations. - /// The amount of time to wait, in seconds, after a break operation before the lease is broken. - /// If this is null then the default time is used. This should be null for acquire, renew, change, and release operations. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage Lease(Uri uri, int? timeout, LeaseAction action, string proposedLeaseId, int? leaseDuration, int? leaseBreakPeriod, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = GetContainerUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "lease"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - - // Add Headers - BlobHttpRequestMessageFactory.AddLeaseAction(request, action); - BlobHttpRequestMessageFactory.AddLeaseDuration(request, leaseDuration); - BlobHttpRequestMessageFactory.AddProposedLeaseId(request, proposedLeaseId); - BlobHttpRequestMessageFactory.AddLeaseBreakPeriod(request, leaseBreakPeriod); - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpRequestMessage request, IDictionary metadata) - { - HttpRequestMessageFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpRequestMessage request, string name, string value) - { - HttpRequestMessageFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to return a listing of all containers in this storage account. - /// - /// The absolute URI for the account. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// Additional details to return with the listing. - /// A web request for the specified operation. - public static HttpRequestMessage List(Uri uri, int? timeout, ListingContext listingContext, ContainerListingDetails detailsIncluded, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - } - - if ((detailsIncluded & ContainerListingDetails.Metadata) != 0) - { - builder.Add("include", "metadata"); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetAcl(Uri uri, int? timeout, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.GetAcl(uri, timeout, GetContainerUriQueryBuilder(), content, operationContext); - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Constructs a web request to set the ACL for a container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// The type of public access to allow for the container. - /// The access condition to apply to the request. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetAcl(Uri uri, int? timeout, BlobContainerPublicAccessType publicAccess, AccessCondition accessCondition, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetAcl(uri, timeout, GetContainerUriQueryBuilder(), content, operationContext); - - if (publicAccess != BlobContainerPublicAccessType.Off) - { - request.Headers.Add(Constants.HeaderConstants.ContainerPublicAccessType, publicAccess.ToString().ToLower()); - } - - request.ApplyAccessCondition(accessCondition); - return request; - } - - /// - /// Generates a web request to return a listing of all blobs in the container. - /// - /// The absolute URI to the container. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// A web request to use to perform the operation. - public static HttpRequestMessage ListBlobs(Uri uri, int? timeout, BlobListingContext listingContext, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = ContainerHttpRequestMessageFactory.GetContainerUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Delimiter != null) - { - builder.Add("delimiter", listingContext.Delimiter); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - - if (listingContext.Details != BlobListingDetails.None) - { - StringBuilder sb = new StringBuilder(); - - bool started = false; - - if ((listingContext.Details & BlobListingDetails.Snapshots) == BlobListingDetails.Snapshots) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("snapshots"); - } - - if ((listingContext.Details & BlobListingDetails.UncommittedBlobs) == BlobListingDetails.UncommittedBlobs) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("uncommittedblobs"); - } - - if ((listingContext.Details & BlobListingDetails.Metadata) == BlobListingDetails.Metadata) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("metadata"); - } - - if ((listingContext.Details & BlobListingDetails.Copy) == BlobListingDetails.Copy) - { - if (!started) - { - started = true; - } - else - { - sb.Append(","); - } - - sb.Append("copy"); - } - - builder.Add("include", sb.ToString()); - } - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Gets the container Uri query builder. - /// - /// A for the container. - internal static UriQueryBuilder GetContainerUriQueryBuilder() - { - UriQueryBuilder uriBuilder = new UriQueryBuilder(); - uriBuilder.Add(Constants.QueryConstants.ResourceType, "container"); - return uriBuilder; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpResponseParsers.cs deleted file mode 100644 index 89d09699f4d03..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Blob/Protocol/ContainerHttpResponseParsers.cs +++ /dev/null @@ -1,78 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net.Http; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static partial class ContainerHttpResponseParsers - { - /// - /// Gets the container's properties from the response. - /// - /// The web response. - /// The container's attributes. - public static BlobContainerProperties GetProperties(HttpResponseMessage response) - { - // Set the container properties - BlobContainerProperties containerProperties = new BlobContainerProperties(); - containerProperties.ETag = (response.Headers.ETag == null) ? null : - response.Headers.ETag.ToString(); - - if (response.Content != null) - { - containerProperties.LastModified = response.Content.Headers.LastModified; - } - else - { - containerProperties.LastModified = null; - } - - // Get lease properties - containerProperties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(response); - containerProperties.LeaseState = BlobHttpResponseParsers.GetLeaseState(response); - containerProperties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(response); - - return containerProperties; - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - public static IDictionary GetMetadata(HttpResponseMessage response) - { - return HttpResponseParsers.GetMetadata(response); - } - - /// - /// Gets the ACL for the container from the response. - /// - /// The web response. - /// A value indicating the public access level for the container. - public static BlobContainerPublicAccessType GetAcl(HttpResponseMessage response) - { - string acl = response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.BlobPublicAccess); - return GetContainerAcl(acl); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/ICanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/ICanonicalizer.cs deleted file mode 100644 index f152ac376f04b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/ICanonicalizer.cs +++ /dev/null @@ -1,29 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using System; - using System.Net.Http; - - internal interface ICanonicalizer - { - string AuthorizationScheme { get; } - - string CanonicalizeHttpRequest(HttpRequestMessage request, string accountName); - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyCanonicalizer.cs deleted file mode 100644 index e56aea30efdde..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyCanonicalizer.cs +++ /dev/null @@ -1,105 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Net.Http; - - internal sealed class SharedKeyCanonicalizer : ICanonicalizer - { - private const string SharedKeyAuthorizationScheme = "SharedKey"; - - private static SharedKeyCanonicalizer instance = new SharedKeyCanonicalizer(); - - public static SharedKeyCanonicalizer Instance - { - get - { - return SharedKeyCanonicalizer.instance; - } - } - - private SharedKeyCanonicalizer() - { - } - - public string AuthorizationScheme - { - get - { - return SharedKeyAuthorizationScheme; - } - } - - public string CanonicalizeHttpRequest(HttpRequestMessage request, string accountName) - { - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method.Method); - - // Add the Content-* HTTP headers. Empty values are allowed. - if (request.Content != null) - { - canonicalizedString.AppendCanonicalizedElement(HttpWebUtility.CombineHttpHeaderValues(request.Content.Headers.ContentEncoding)); - canonicalizedString.AppendCanonicalizedElement(HttpWebUtility.CombineHttpHeaderValues(request.Content.Headers.ContentLanguage)); - AuthenticationUtility.AppendCanonicalizedContentLengthHeader(canonicalizedString, request); - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentMD5 == null) ? null : - Convert.ToBase64String(request.Content.Headers.ContentMD5)); - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentType == null) ? null : - request.Content.Headers.ContentType.ToString()); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - canonicalizedString.AppendCanonicalizedElement(null); - if (request.Method == HttpMethod.Put || request.Method == HttpMethod.Delete) - { - canonicalizedString.AppendCanonicalizedElement("0"); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - } - - canonicalizedString.AppendCanonicalizedElement(null); - canonicalizedString.AppendCanonicalizedElement(null); - } - - // Add the Date HTTP header (only if the x-ms-date header is not being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request); - - // Add If-* headers and Range header - canonicalizedString.AppendCanonicalizedElement(AuthenticationUtility.GetCanonicalizedHeaderValue(request.Headers.IfModifiedSince)); - canonicalizedString.AppendCanonicalizedElement(CommonUtility.GetFirstHeaderValue(request.Headers.IfMatch)); - canonicalizedString.AppendCanonicalizedElement(CommonUtility.GetFirstHeaderValue(request.Headers.IfNoneMatch)); - canonicalizedString.AppendCanonicalizedElement(AuthenticationUtility.GetCanonicalizedHeaderValue(request.Headers.IfUnmodifiedSince)); - canonicalizedString.AppendCanonicalizedElement((request.Headers.Range == null) ? null : - CommonUtility.GetFirstHeaderValue(request.Headers.Range.Ranges)); - - // Add any custom headers - AuthenticationUtility.AppendCanonicalizedCustomHeaders(canonicalizedString, request); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteCanonicalizer.cs deleted file mode 100644 index 4e17c8725aeb4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteCanonicalizer.cs +++ /dev/null @@ -1,87 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - using System.Text; - - internal sealed class SharedKeyLiteCanonicalizer : ICanonicalizer - { - private const string SharedKeyLiteAuthorizationScheme = "SharedKeyLite"; - private const int ExpectedCanonicalizedStringLength = 250; - - private static SharedKeyLiteCanonicalizer instance = new SharedKeyLiteCanonicalizer(); - - public static SharedKeyLiteCanonicalizer Instance - { - get - { - return SharedKeyLiteCanonicalizer.instance; - } - } - - private SharedKeyLiteCanonicalizer() - { - } - - public string AuthorizationScheme - { - get - { - return SharedKeyLiteAuthorizationScheme; - } - } - - public string CanonicalizeHttpRequest(HttpRequestMessage request, string accountName) - { - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method.Method, ExpectedCanonicalizedStringLength); - - // Add the Content-* HTTP headers. Empty values are allowed. - if (request.Content != null) - { - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentMD5 == null) ? null : - Convert.ToBase64String(request.Content.Headers.ContentMD5)); - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentType == null) ? null : - request.Content.Headers.ContentType.ToString()); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - canonicalizedString.AppendCanonicalizedElement(null); - } - - // Add the Date HTTP header (only if the x-ms-date header is not being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request); - - // Add any custom headers - AuthenticationUtility.AppendCanonicalizedCustomHeaders(canonicalizedString, request); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteTableCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteTableCanonicalizer.cs deleted file mode 100644 index d2bf8f7be289a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyLiteTableCanonicalizer.cs +++ /dev/null @@ -1,68 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - using System.Text; - - internal sealed class SharedKeyLiteTableCanonicalizer : ICanonicalizer - { - private const string SharedKeyLiteAuthorizationScheme = "SharedKeyLite"; - private const int ExpectedCanonicalizedStringLength = 150; - - private static SharedKeyLiteTableCanonicalizer instance = new SharedKeyLiteTableCanonicalizer(); - - public static SharedKeyLiteTableCanonicalizer Instance - { - get - { - return SharedKeyLiteTableCanonicalizer.instance; - } - } - - private SharedKeyLiteTableCanonicalizer() - { - } - - public string AuthorizationScheme - { - get - { - return SharedKeyLiteAuthorizationScheme; - } - } - - public string CanonicalizeHttpRequest(HttpRequestMessage request, string accountName) - { - // Add the Date HTTP header (or the x-ms-date header if it is being used) - string dateHeaderValue = AuthenticationUtility.GetPreferredDateHeaderValue(request); - CanonicalizedString canonicalizedString = new CanonicalizedString(dateHeaderValue, ExpectedCanonicalizedStringLength); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyTableCanonicalizer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyTableCanonicalizer.cs deleted file mode 100644 index f4095cda8dd5c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Auth/SharedKeyTableCanonicalizer.cs +++ /dev/null @@ -1,84 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Auth -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - using System.Text; - - internal sealed class SharedKeyTableCanonicalizer : ICanonicalizer - { - private const string SharedKeyAuthorizationScheme = "SharedKey"; - private const int ExpectedCanonicalizedStringLength = 200; - - private static SharedKeyTableCanonicalizer instance = new SharedKeyTableCanonicalizer(); - - public static SharedKeyTableCanonicalizer Instance - { - get - { - return SharedKeyTableCanonicalizer.instance; - } - } - - private SharedKeyTableCanonicalizer() - { - } - - public string AuthorizationScheme - { - get - { - return SharedKeyAuthorizationScheme; - } - } - - public string CanonicalizeHttpRequest(HttpRequestMessage request, string accountName) - { - // Add the method (GET, POST, PUT, or HEAD). - CanonicalizedString canonicalizedString = new CanonicalizedString(request.Method.Method, ExpectedCanonicalizedStringLength); - - // Add the Content-* HTTP headers. Empty values are allowed. - if (request.Content != null) - { - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentMD5 == null) ? null : - Convert.ToBase64String(request.Content.Headers.ContentMD5)); - canonicalizedString.AppendCanonicalizedElement((request.Content.Headers.ContentType == null) ? null : - request.Content.Headers.ContentType.ToString()); - } - else - { - canonicalizedString.AppendCanonicalizedElement(null); - canonicalizedString.AppendCanonicalizedElement(null); - } - - // Add the Date HTTP header (or the x-ms-date header if it is being used) - AuthenticationUtility.AppendCanonicalizedDateHeader(canonicalizedString, request, true); - - // Add the canonicalized URI element - string resourceString = AuthenticationUtility.GetCanonicalizedResourceString(request.RequestUri, accountName, true); - canonicalizedString.AppendCanonicalizedElement(resourceString); - - return canonicalizedString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Executor/Executor.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Executor/Executor.cs deleted file mode 100644 index 716caa3504e0e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Executor/Executor.cs +++ /dev/null @@ -1,267 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Executor -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Net.Http; - using System.Threading; - using System.Threading.Tasks; - - internal class Executor : ExecutorBase - { - #region IAsyncAction - public static Task ExecuteAsyncNullReturn(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext) - { - return ExecuteAsyncNullReturn(cmd, policy, operationContext, CancellationToken.None); - } - - public static Task ExecuteAsyncNullReturn(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) - { - return ExecuteAsyncInternal(cmd, policy, operationContext, token); - } - #endregion - - #region IAsyncOperation - public static Task ExecuteAsync(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext) - { - return ExecuteAsync(cmd, policy, operationContext, CancellationToken.None); - } - - public static Task ExecuteAsync(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) - { - return ExecuteAsyncInternal(cmd, policy, operationContext, token); - } - #endregion - - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed.")] - private async static Task ExecuteAsyncInternal(RESTCommand cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) - { - // Note all code below will reference state, not params directly, this will allow common code with multiple executors (APM, Sync, Async) - using (ExecutionState executionState = new ExecutionState(cmd, policy, operationContext)) - { - bool shouldRetry = false; - TimeSpan delay = TimeSpan.Zero; - - // Create a new client - HttpClient client = cmd.BuildClient(cmd, executionState.OperationContext); - client.Timeout = TimeSpan.FromMilliseconds(int.MaxValue); - - do - { - try - { - executionState.Init(); - - // 0. Begin Request - Executor.StartRequestAttempt(executionState); - - // 1. Build request and content - executionState.CurrentOperation = ExecutorOperation.BeginOperation; - - // Content is re-created every retry, as HttpClient disposes it after a successful request - HttpContent content = cmd.BuildContent != null ? cmd.BuildContent(cmd, executionState.OperationContext) : null; - - // This is so the old auth header etc is cleared out, the content is where serialization occurs which is the major perf hit - Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestAsync, cmd.Uri); - executionState.Req = cmd.BuildRequest(cmd, content, executionState.OperationContext); - - // 2. Set Headers - Executor.ApplyUserHeaders(executionState); - - // Let the user know we are ready to send - Executor.FireSendingRequest(executionState); - - // 3. Sign Request is not needed, as HttpClient will call us - - // 4. Set timeout - if (executionState.OperationExpiryTime.HasValue) - { - client.Timeout = executionState.RemainingTimeout; - } - - Executor.CheckTimeout(executionState, true); - } - catch (Exception ex) - { - Logger.LogError(executionState.OperationContext, SR.TraceInitRequestError, ex.Message); - - // Store exception and throw here. All operations in this try would be non-retryable by default - StorageException storageEx = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); - storageEx.IsRetryable = false; - executionState.ExceptionRef = storageEx; -#if WINDOWS_RT - // Need to throw wrapped Exception with message as serialized exception info stuff. - int hResult = WrappedStorageException.GenerateHResult(executionState.ExceptionRef, executionState.Cmd.CurrentResult); - throw new WrappedStorageException(executionState.Cmd.CurrentResult.WriteAsXml(), executionState.ExceptionRef, hResult); -#else - throw executionState.ExceptionRef; // throw base exception for desktop -#endif - } - - // Enter Retryable Section of execution - try - { - // Send Request - executionState.CurrentOperation = ExecutorOperation.BeginGetResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceGetResponse); - executionState.Resp = await client.SendAsync(executionState.Req, HttpCompletionOption.ResponseHeadersRead, token); - executionState.CurrentOperation = ExecutorOperation.EndGetResponse; - - // Since HttpClient wont throw for non success, manually check and populate an exception - if (!executionState.Resp.IsSuccessStatusCode) - { - executionState.ExceptionRef = await Exceptions.PopulateStorageExceptionFromHttpResponseMessage(executionState.Resp, executionState.Cmd.CurrentResult); - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); - Executor.FireResponseReceived(executionState); - - // 7. Do Response parsing (headers etc, no stream available here) - if (cmd.PreProcessResponse != null) - { - executionState.CurrentOperation = ExecutorOperation.PreProcess; - executionState.Result = cmd.PreProcessResponse(cmd, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); - - // clear exception - executionState.ExceptionRef = null; - Logger.LogInformational(executionState.OperationContext, SR.TracePreProcessDone); - } - - // 8. (Potentially reads stream from server) - executionState.CurrentOperation = ExecutorOperation.GetResponseStream; - cmd.ResponseStream = await executionState.Resp.Content.ReadAsStreamAsync(); - - if (!cmd.RetrieveResponseStream) - { - cmd.DestinationStream = Stream.Null; - } - - if (cmd.DestinationStream != null) - { - if (cmd.StreamCopyState == null) - { - cmd.StreamCopyState = new StreamDescriptor(); - } - - try - { - executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; - Logger.LogInformational(executionState.OperationContext, SR.TraceDownload); - await cmd.ResponseStream.WriteToAsync(cmd.DestinationStream, null /* copyLength */, null /* maxLength */, cmd.CalculateMd5ForResponseStream, executionState, cmd.StreamCopyState, token); - } - finally - { - cmd.ResponseStream.Dispose(); - cmd.ResponseStream = null; - } - } - - // 9. Evaluate Response & Parse Results, (Stream potentially available here) - if (cmd.PostProcessResponse != null) - { - executionState.CurrentOperation = ExecutorOperation.PostProcess; - Logger.LogInformational(executionState.OperationContext, SR.TracePostProcess); - executionState.Result = await cmd.PostProcessResponse(cmd, executionState.Resp, executionState.OperationContext); - } - - executionState.CurrentOperation = ExecutorOperation.EndOperation; - Logger.LogInformational(executionState.OperationContext, SR.TraceSuccess); - Executor.FinishRequestAttempt(executionState); - - return executionState.Result; - } - catch (Exception e) - { - Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, e.Message); - Executor.FinishRequestAttempt(executionState); - - if (e is TaskCanceledException && (executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - e = new TimeoutException(SR.TimeoutExceptionMessage, e); - } - - StorageException translatedException = StorageException.TranslateException(e, executionState.Cmd.CurrentResult); - executionState.ExceptionRef = translatedException; - Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); - - shouldRetry = false; - if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) - { - shouldRetry = executionState.RetryPolicy.ShouldRetry( - executionState.RetryCount++, - executionState.Cmd.CurrentResult.HttpStatusCode, - executionState.ExceptionRef, - out delay, - executionState.OperationContext); - - if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) - { - delay = Constants.MaximumRetryBackoff; - } - } - } - finally - { - if (executionState.Resp != null) - { - executionState.Resp.Dispose(); - executionState.Resp = null; - } - } - - // potentially backoff - if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) - { - Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); -#if WINDOWS_RT - // Need to throw wrapped Exception with message as serialized exception info stuff. - int hResult = WrappedStorageException.GenerateHResult(executionState.ExceptionRef, executionState.Cmd.CurrentResult); - throw new WrappedStorageException(executionState.Cmd.CurrentResult.WriteAsXml(), executionState.ExceptionRef, hResult); -#else - throw executionState.ExceptionRef; // throw base exception for desktop -#endif - } - else - { - if (cmd.RecoveryAction != null) - { - // I.E. Rewind stream etc. - cmd.RecoveryAction(cmd, executionState.Cmd.CurrentResult.Exception, executionState.OperationContext); - } - - if (delay > TimeSpan.Zero) - { - await Task.Delay(delay, token); - } - - Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); - } - } - while (shouldRetry); - - // should never get here - throw new NotImplementedException(SR.InternalStorageError); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Logger.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Logger.cs deleted file mode 100644 index 121a6611db24a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Logger.cs +++ /dev/null @@ -1,64 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.Tracing; - - internal static partial class Logger - { - private static StorageEventSource eventSource = new StorageEventSource(); - - internal static void LogError(OperationContext operationContext, string format, params object[] args) - { - if (Logger.eventSource.IsEnabled() && - Logger.ShouldLog(LogLevel.Error, operationContext)) - { - Logger.eventSource.Error(Logger.FormatLine(operationContext, format, args)); - } - } - - internal static void LogWarning(OperationContext operationContext, string format, params object[] args) - { - if (Logger.eventSource.IsEnabled() && - Logger.ShouldLog(LogLevel.Warning, operationContext)) - { - Logger.eventSource.Warning(Logger.FormatLine(operationContext, format, args)); - } - } - - internal static void LogInformational(OperationContext operationContext, string format, params object[] args) - { - if (Logger.eventSource.IsEnabled() && - Logger.ShouldLog(LogLevel.Informational, operationContext)) - { - Logger.eventSource.Informational(Logger.FormatLine(operationContext, format, args)); - } - } - - internal static void LogVerbose(OperationContext operationContext, string format, params object[] args) - { - if (Logger.eventSource.IsEnabled() && - Logger.ShouldLog(LogLevel.Verbose, operationContext)) - { - Logger.eventSource.Verbose(Logger.FormatLine(operationContext, format, args)); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/StorageEventSource.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/StorageEventSource.cs deleted file mode 100644 index d00acf6cdcd0e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/StorageEventSource.cs +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Diagnostics.Tracing; - - [EventSource(Name = Constants.LogSourceName)] - internal class StorageEventSource : EventSource - { - internal StorageEventSource() - { - } - - [Event(1, Level = EventLevel.Error)] - internal void Error(string message) - { - this.WriteEvent(1, message); - } - - [Event(2, Level = EventLevel.Warning)] - internal void Warning(string message) - { - this.WriteEvent(2, message); - } - - [Event(3, Level = EventLevel.Informational)] - internal void Informational(string message) - { - this.WriteEvent(3, message); - } - - [Event(4, Level = EventLevel.Verbose)] - internal void Verbose(string message) - { - this.WriteEvent(4, message); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/AsyncSemaphore.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/AsyncSemaphore.cs deleted file mode 100644 index c34bd9d82b580..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/AsyncSemaphore.cs +++ /dev/null @@ -1,75 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Threading.Tasks; - - /// - /// This class provides asynchronous semaphore functionality (based on Stephen Toub's blog). - /// - [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed - Stephen Toub is a proper noun.")] - internal partial class AsyncSemaphore - { - private readonly static Task CompletedTask = Task.FromResult(true); - - private readonly Queue> pendingWaits = - new Queue>(); - - public Task WaitAsync() - { - lock (this.pendingWaits) - { - if (this.count > 0) - { - this.count--; - return AsyncSemaphore.CompletedTask; - } - else - { - TaskCompletionSource waiter = new TaskCompletionSource(); - this.pendingWaits.Enqueue(waiter); - return waiter.Task; - } - } - } - - public void Release() - { - TaskCompletionSource waiter = null; - lock (this.pendingWaits) - { - if (this.pendingWaits.Count > 0) - { - waiter = this.pendingWaits.Dequeue(); - } - else - { - this.count++; - } - } - - if (waiter != null) - { - waiter.SetResult(false); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/CultureStringComparer.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/CultureStringComparer.cs deleted file mode 100644 index 23fad238dcda9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/CultureStringComparer.cs +++ /dev/null @@ -1,75 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Globalization; - - /// - /// Represents a string comparison operation that uses specific case and culture-based rules. - /// - internal class CultureStringComparer : StringComparer - { - private CultureInfo cultureInfo; - private CompareOptions compareOptions; - - /// - /// Creates a CultureStringComparer object that compares strings according to the rules of a specified culture. - /// - /// A culture whose linguistic rules are used to perform a string comparison. - /// true to specify that comparison operations be case-insensitive; false to specify that comparison operations be case-sensitive. - public CultureStringComparer(CultureInfo culture, bool ignoreCase) - : base() - { - this.cultureInfo = culture; - this.compareOptions = ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None; - } - - /// - /// Compares two strings and returns an indication of their relative sort order. - /// - /// A string to compare to y. - /// A string to compare to x. - /// A signed integer that indicates the relative values of x and y. - public override int Compare(string x, string y) - { - return this.cultureInfo.CompareInfo.Compare(x, y, this.compareOptions); - } - - /// - /// Indicates whether two strings are equal. - /// - /// A string to compare to y. - /// A string to compare to x. - /// true if x and y refer to the same object, or x and y are equal; otherwise, false. - public override bool Equals(string x, string y) - { - return this.Compare(x, y) == 0; - } - - /// - /// Gets the hash code for the specified object. - /// - /// An object. - /// A 32-bit signed hash code calculated from the value of the parameter. - public override int GetHashCode(string obj) - { - return obj.GetHashCode(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/HttpResponseMessageUtils.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/HttpResponseMessageUtils.cs deleted file mode 100644 index 9a216a2fc0343..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/HttpResponseMessageUtils.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Linq; - using System.Net.Http.Headers; - - internal static class HttpResponseMessageUtils - { - /// - /// Gets the first header value for a specified header or an empty string if it does not exist. - /// - /// A collection of headers and their values. - /// The name of the header to return. - /// The first header value or an empty string if the header does not exist. - public static string GetHeaderSingleValueOrDefault(this HttpHeaders headers, string name) - { - if (headers.Contains(name)) - { - return CommonUtility.GetFirstHeaderValue(headers.GetValues(name)); - } - - return string.Empty; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/WindowsAzureErrorCode.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/WindowsAzureErrorCode.cs deleted file mode 100644 index 0fb6382924498..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Core/Util/WindowsAzureErrorCode.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Linq; - using System.Net; - using System.Text; - using System.Threading.Tasks; - - /// - /// A collection of well-known error codes. - /// - /// - [SuppressMessage("StyleCop.CSharp.LayoutRules", "*", Justification = "For Readability.")] - [SuppressMessage("StyleCop.CSharp.SpacingRules", "*", Justification = "For Readability.")] - public sealed class WindowsAzureErrorCode - { - // Internal HRESULT structure: - // Bits 31 - 16: HRESULT flags indicating an error (Severity: ERROR; facility: ITF) - // Bits 12 - 15: error source (HTTP, WRAP, etc) - // Bits 0 - 11: source-specific information, if any. Contains status code for HTTP errors. - - // Basic error code mark - internal const int ComErrorMask = unchecked((int)0x80040000); // Mask for all COM error codes - internal const int HttpErrorMask = ComErrorMask | 0x1000; // Mask for HTTP exceptions - internal const int ClientErrorMask = ComErrorMask | 0x2000; // Mask for exceptions from client side. - - // HTTP status mapping - public static int HttpBadRequest { get { return HttpErrorMask | (int)HttpStatusCode.BadRequest; } } - public static int HttpUnauthorized { get { return HttpErrorMask | (int)HttpStatusCode.Unauthorized; } } - public static int HttpPaymentRequired { get { return HttpErrorMask | (int)HttpStatusCode.PaymentRequired; } } - public static int HttpForbidden { get { return HttpErrorMask | (int)HttpStatusCode.Forbidden; } } - public static int HttpNotFound { get { return HttpErrorMask | (int)HttpStatusCode.NotFound; } } - public static int HttpMethodNotAllowed { get { return HttpErrorMask | (int)HttpStatusCode.MethodNotAllowed; } } - public static int HttpNotAcceptable { get { return HttpErrorMask | (int)HttpStatusCode.NotAcceptable; } } - public static int HttpProxyAuthenticationRequired { get { return HttpErrorMask | (int)HttpStatusCode.ProxyAuthenticationRequired; } } - public static int HttpRequestTimeout { get { return HttpErrorMask | (int)HttpStatusCode.RequestTimeout; } } - public static int HttpConflict { get { return HttpErrorMask | (int)HttpStatusCode.Conflict; } } - public static int HttpGone { get { return HttpErrorMask | (int)HttpStatusCode.Gone; } } - public static int HttpLengthRequired { get { return HttpErrorMask | (int)HttpStatusCode.LengthRequired; } } - public static int HttpPreconditionFailed { get { return HttpErrorMask | (int)HttpStatusCode.PreconditionFailed; } } - public static int HttpRequestEntityTooLarge { get { return HttpErrorMask | (int)HttpStatusCode.RequestEntityTooLarge; } } - public static int HttpRequestUriTooLong { get { return HttpErrorMask | (int)HttpStatusCode.RequestUriTooLong; } } - public static int HttpUnsupportedMediaType { get { return HttpErrorMask | (int)HttpStatusCode.UnsupportedMediaType; } } - public static int HttpRequestedRangeNotSatisfiable { get { return HttpErrorMask | (int)HttpStatusCode.RequestedRangeNotSatisfiable; } } - public static int HttpExpectationFailed { get { return HttpErrorMask | (int)HttpStatusCode.ExpectationFailed; } } - public static int HttpUpgradeRequired { get { return HttpErrorMask | (int)HttpStatusCode.UpgradeRequired; } } - public static int HttpInternalServerError { get { return HttpErrorMask | (int)HttpStatusCode.InternalServerError; } } - public static int HttpNotImplemented { get { return HttpErrorMask | (int)HttpStatusCode.NotImplemented; } } - public static int HttpBadGateway { get { return HttpErrorMask | (int)HttpStatusCode.BadGateway; } } - public static int HttpServiceUnavailable { get { return HttpErrorMask | (int)HttpStatusCode.ServiceUnavailable; } } - public static int HttpGatewayTimeout { get { return HttpErrorMask | (int)HttpStatusCode.GatewayTimeout; } } - public static int HttpVersionNotSupported { get { return HttpErrorMask | (int)HttpStatusCode.HttpVersionNotSupported; } } - - // Client side exception. - public static int UnknownException { get { return ClientErrorMask | (int)0xfff; } } - - // Pre-defined hresult code. - public static int TimeoutException { get { return unchecked((int)0x80131505); } } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.Edm.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.Edm.Portable.dll deleted file mode 100644 index 545d84e308174..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.Edm.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.OData.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.OData.Portable.dll deleted file mode 100644 index 56a64aa61112e..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/Microsoft.Data.OData.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/System.Spatial.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/System.Spatial.Portable.dll deleted file mode 100644 index a7d191c73050b..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/RT/Dependencies/System.Spatial.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/ExceptionInfo.cs b/microsoft-azure-api/Services/Storage/Lib/RT/ExceptionInfo.cs deleted file mode 100644 index 9594054a96dbf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/ExceptionInfo.cs +++ /dev/null @@ -1,152 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - using System.Xml; - using Microsoft.WindowsAzure.Storage.Core.Util; - - /// - /// Represents exception information from a request to the Storage service. - /// - public sealed class ExceptionInfo - { - /// - /// Gets the type of the exception. - /// - /// The type of the exception. - public string Type { get; internal set; } - - /// - /// Gets HRESULT, a coded numerical value that is assigned to a specific exception. - /// - /// The HRESULT value. - public int HResult { get; internal set; } - - /// - /// Gets a message that describes the current exception. - /// - /// The error message that explains the reason for the exception, or an empty string(""). - public string Message { get; internal set; } - - /// - /// Gets the name of the operation that causes the error. - /// - /// The name of the operation that causes the error. - public string Source { get; internal set; } - - /// - /// Gets a string representation of the frames on the call stack at the time the current exception was thrown. - /// - /// The frames on the call stack at the time the current exception was thrown. - public string StackTrace { get; internal set; } - - /// - /// Gets the instance that caused the current exception. - /// - /// An instance of that describes the error that caused the current exception. - public ExceptionInfo InnerExceptionInfo { get; internal set; } - - /// - /// Initializes a new instance of the class. - /// - public ExceptionInfo() - { - } - - internal ExceptionInfo(Exception ex) - { - this.Type = ex.GetType().Name; - this.Message = ex.Message; - this.StackTrace = ex.StackTrace; -#if WINDOWS_RT - this.HResult = ex.HResult; -#endif - - this.Source = ex.Source; - if (ex.InnerException != null) - { - this.InnerExceptionInfo = new ExceptionInfo(ex.InnerException); - } - } - - internal static ExceptionInfo ReadFromXMLReader(XmlReader reader) - { - ExceptionInfo res = new ExceptionInfo(); - try - { - res.ReadXml(reader); - } - catch (XmlException) - { - return null; - } - - return res; - } - - #region IXMLSerializable - - internal void WriteXml(XmlWriter writer) - { - writer.WriteStartElement("ExceptionInfo"); - writer.WriteElementString("Type", this.Type); -#if WINDOWS_RT - writer.WriteElementString("HResult", Convert.ToString(this.HResult)); -#endif - writer.WriteElementString("Message", this.Message); - writer.WriteElementString("Source", this.Source); - writer.WriteElementString("StackTrace", this.StackTrace); - - if (this.InnerExceptionInfo != null) - { - writer.WriteStartElement("InnerExceptionInfo"); - this.InnerExceptionInfo.WriteXml(writer); - writer.WriteEndElement(); - } - - // End ExceptionInfo - writer.WriteEndElement(); - } - - internal void ReadXml(XmlReader reader) - { - reader.ReadStartElement("ExceptionInfo"); - this.Type = CommonUtility.ReadElementAsString("Type", reader); - -#if WINDOWS_RT - this.HResult = int.Parse(CommonUtility.ReadElementAsString("HResult", reader)); -#endif - this.Message = CommonUtility.ReadElementAsString("Message", reader); - this.Source = CommonUtility.ReadElementAsString("Source", reader); - this.StackTrace = CommonUtility.ReadElementAsString("StackTrace", reader); - - if (reader.IsStartElement() && reader.LocalName == "InnerExceptionInfo") - { - reader.ReadStartElement("InnerExceptionInfo"); - this.InnerExceptionInfo = ReadFromXMLReader(reader); - reader.ReadEndElement(); - } - - // End ExceptionInfo - reader.ReadEndElement(); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Lib/RT/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/RT/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Properties/AssemblyInfo.cs deleted file mode 100644 index b1188566304f5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.Storage.WinMD")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] -[assembly: ComVisible(false)] - -#if SIGN -[assembly: InternalsVisibleTo( - "Microsoft.WindowsAzure.StorageRT.Test, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67" + - "871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0b" + - "d333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307" + - "e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c3" + - "08055da9")] -[assembly: InternalsVisibleTo( - "Microsoft.WindowsAzure.Storage.Table, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67" + - "871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0b" + - "d333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307" + - "e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c3" + - "08055da9")] -#else -[assembly: InternalsVisibleTo("Microsoft.WindowsAzure.StorageRT.Test")] -[assembly: InternalsVisibleTo("Microsoft.WindowsAzure.Storage.Table")] -#endif -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueue.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueue.cs deleted file mode 100644 index c821c860ad460..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueue.cs +++ /dev/null @@ -1,1113 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - /// - /// This class represents a queue in the Windows Azure Queue service. - /// - public sealed partial class CloudQueue - { - /// - /// Creates the queue. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync() - { - return this.CreateAsync(null /* options */, null /* operationContext */); - } - - /// - /// Creates the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction CreateAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.CreateQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Creates the queue if it does not already exist. - /// - /// true if the queue did not already exist and was created; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Creates the queue if it does not already exist. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the queue did not already exist and was created; otherwise false. - [DoesServiceRequest] - public IAsyncOperation CreateIfNotExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (exists) - { - return false; - } - - try - { - await this.CreateAsync(modifiedOptions, operationContext).AsTask(token); - - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NoContent) - { - return false; - } - - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == QueueErrorCodeStrings.QueueAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Deletes the queue. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync() - { - return this.DeleteAsync(null /* options */, null /* operationContext */); - } - - /// - /// Deletes the queue. - /// - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.DeleteQueueImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the queue if it already exists. - /// - /// true if the queue already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Deletes the queue if it already exists. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the queue already existed and was deleted; otherwise, false. - [DoesServiceRequest] - public IAsyncOperation DeleteIfExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - bool exists = await this.ExistsAsync(modifiedOptions, operationContext).AsTask(token); - - if (!exists) - { - return false; - } - - try - { - await this.DeleteAsync(modifiedOptions, operationContext).AsTask(token); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == QueueErrorCodeStrings.QueueNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - }); - } - - /// - /// Sets permissions for the queue. - /// - /// The permissions to apply to the queue. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPermissionsAsync(QueuePermissions permissions) - { - return this.SetPermissionsAsync(permissions, null /* options */, null /* operationContext */); - } - - /// - /// Sets permissions for the queue. - /// - /// The permissions to apply to the queue. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetPermissionsAsync(QueuePermissions permissions, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetPermissionsImpl(permissions, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Gets the permissions settings for the queue. - /// - /// The queue's permissions. - [DoesServiceRequest] - public IAsyncOperation GetPermissionsAsync() - { - return this.GetPermissionsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Gets the permissions settings for the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// The queue's permissions. - [DoesServiceRequest] - public IAsyncOperation GetPermissionsAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetPermissionsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Checks existence of the queue. - /// - /// true if the queue exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync() - { - return this.ExistsAsync(null /* options */, null /* operationContext */); - } - - /// - /// Checks existence of the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// true if the queue exists. - [DoesServiceRequest] - public IAsyncOperation ExistsAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.ExistsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Retrieves the queue's attributes. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync() - { - return this.FetchAttributesAsync(null /* options */, null /* operationContext */); - } - - /// - /// Retrieves the queue's attributes. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction FetchAttributesAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.FetchAttributesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Sets the queue's user-defined metadata. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync() - { - return this.SetMetadataAsync(null /* options */, null /* operationContext */); - } - - /// - /// Sets the queue's user-defined metadata. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetMetadataAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetMetadataImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Adds a message to the queue. - /// - /// The message to add. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction AddMessageAsync(CloudQueueMessage message) - { - return this.AddMessageAsync(message, null /* timeToLive */, null /* initialVisibilityDelay */, null /* options */, null /* operationContext */); - } - - /// - /// Adds a message to the queue. - /// - /// The message to add. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction AddMessageAsync(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.AddMessageImpl(message, timeToLive, initialVisibilityDelay, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Updates a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// The message update fields. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields) - { - return this.UpdateMessageAsync(message, visibilityTimeout, updateFields, null /* options */, null /* operationContext */); - } - - /// - /// Updates a message. - /// - /// The message to update. - /// The visibility timeout interval. - /// The message update fields. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction UpdateMessageAsync(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.UpdateMessageImpl(message, visibilityTimeout, updateFields, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Deletes the message. - /// - /// The message to delete. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteMessageAsync(CloudQueueMessage message) - { - return this.DeleteMessageAsync(message, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the message. - /// - /// The message to delete. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteMessageAsync(CloudQueueMessage message, QueueRequestOptions options, OperationContext operationContext) - { - return this.DeleteMessageAsync(message.Id, message.PopReceipt, options, operationContext); - } - - /// - /// Deletes the message. - /// - /// The message ID. - /// The pop receipt value. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteMessageAsync(string messageId, string popReceipt) - { - return this.DeleteMessageAsync(messageId, popReceipt, null /* options */, null /* operationContext */); - } - - /// - /// Deletes the message. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction DeleteMessageAsync(string messageId, string popReceipt, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.DeleteMessageImpl(messageId, popReceipt, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Gets a list of messages from the queue. - /// - /// The number of messages to retrieve. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncOperation> GetMessagesAsync(int messageCount) - { - return this.GetMessagesAsync(messageCount, null /* visibilityTimeout */, null /* options */, null /* operationContext */); - } - - /// - /// Gets a list of messages from the queue. - /// - /// The number of messages to retrieve. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of messages. - [DoesServiceRequest] - public IAsyncOperation> GetMessagesAsync(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetMessagesImpl(messageCount, visibilityTimeout, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Gets a single message from the queue. - /// - /// A message. - [DoesServiceRequest] - public IAsyncOperation GetMessageAsync() - { - return this.GetMessageAsync(null /* visibilityTimeout */, null /* options */, null /* operationContext */); - } - - /// - /// Gets a single message from the queue. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A message. - [DoesServiceRequest] - public IAsyncOperation GetMessageAsync(TimeSpan? visibilityTimeout, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetMessageImpl(visibilityTimeout, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Peeks a list of messages from the queue. - /// - /// The number of messages to retrieve. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncOperation> PeekMessagesAsync(int messageCount) - { - return this.GetMessagesAsync(messageCount, null /* visibilityTimeout */, null /* options */, null /* operationContext */); - } - - /// - /// Peeks a list of messages from the queue. - /// - /// The number of messages to retrieve. - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An enumerable collection of messages. - [DoesServiceRequest] - public IAsyncOperation> PeekMessagesAsync(int messageCount, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.PeekMessagesImpl(messageCount, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Peeks a single message from the queue. - /// - /// A message. - [DoesServiceRequest] - public IAsyncOperation PeekMessageAsync() - { - return this.PeekMessageAsync(null /* options */, null /* operationContext */); - } - - /// - /// Peeks a single message from the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A message. - [DoesServiceRequest] - public IAsyncOperation PeekMessageAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.PeekMessageImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Clears the messages of the queue. - /// - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ClearAsync() - { - return this.ClearAsync(null /* options */, null /* operationContext */); - } - - /// - /// Clears the messages of the queue. - /// - /// A object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction ClearAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.ClearImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - /// - /// Implementation for the Create method. - /// - /// A object that specifies additional options for the request. - /// A that creates the queue. - private RESTCommand CreateQueueImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = QueueHttpRequestMessageFactory.Create(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - QueueHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpStatusCode[] expectedHttpStatusCodes = new HttpStatusCode[2]; - expectedHttpStatusCodes[0] = HttpStatusCode.Created; - expectedHttpStatusCodes[1] = HttpStatusCode.NoContent; - HttpResponseParsers.ProcessExpectedStatusCodeNoException(expectedHttpStatusCodes, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the Delete method. - /// - /// A object that specifies additional options for the request. - /// A that deletes the queue. - private RESTCommand DeleteQueueImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.Delete(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the Clear method. - /// - /// A object that specifies additional options for the request. - /// A that deletes the queue. - private RESTCommand ClearImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.Delete(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the FetchAttributes method. - /// - /// A object that specifies additional options for the request. - /// A that fetches the attributes. - private RESTCommand FetchAttributesImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetMetadata(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return getCmd; - } - - /// - /// Implementation for the Exists method. - /// - /// A object that specifies additional options for the request. - /// A that checks existence. - private RESTCommand ExistsImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetMetadata(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return false; - } - - if (resp.StatusCode == HttpStatusCode.PreconditionFailed) - { - return true; - } - - return HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, true, cmd, ex); - }; - - return getCmd; - } - - /// - /// Implementation for the SetMetadata method. - /// - /// A object that specifies additional options for the request. - /// A that sets the metadata. - private RESTCommand SetMetadataImpl(QueueRequestOptions options) - { - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => - { - HttpRequestMessage msg = QueueHttpRequestMessageFactory.SetMetadata(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - QueueHttpRequestMessageFactory.AddMetadata(msg, this.Metadata); - return msg; - }; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the SetPermissions method. - /// - /// The permissions to set. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand SetPermissionsImpl(QueuePermissions acl, QueueRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - QueueRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.SetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetPermissionsImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - this.GetMessageCountAndMetadataFromResponse(resp); - return Task.Factory.StartNew(() => - { - QueuePermissions queueAcl = new QueuePermissions(); - QueueHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, queueAcl); - return queueAcl; - }); - }; - - return getCmd; - } - - /// - /// Implementation for the AddMessage method. - /// - /// The message. - /// The maximum time to allow the message to be in the queue, or null. - /// The length of time from now during which the message will be invisible. - /// If null then the message will be visible immediately. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand AddMessageImpl(CloudQueueMessage message, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, QueueRequestOptions options) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - QueueRequest.WriteMessageContent(message.GetMessageContentForTransfer(this.EncodeMessage), memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.AddMessage(cmd.Uri, cmd.ServerTimeoutInSeconds, timeToLive, initialVisibilityDelay, cnt, ctx); - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null, cmd, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); - GetMessageCountAndMetadataFromResponse(resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the UpdateMessage method. - /// - /// The message to update. - /// The visibility timeout interval. - /// The message update fields. - /// A object that specifies additional options for the request. - /// A that sets the permissions. - private RESTCommand UpdateMessageImpl(CloudQueueMessage message, TimeSpan visibilityTimeout, MessageUpdateFields updateFields, QueueRequestOptions options) - { - CommonUtility.AssertNotNull("message", message); - CommonUtility.AssertNotNullOrEmpty("messageId", message.Id); - CommonUtility.AssertNotNullOrEmpty("popReceipt", message.PopReceipt); - CommonUtility.AssertInBounds("visibilityTimeout", visibilityTimeout, TimeSpan.Zero, CloudQueueMessage.MaxTimeToLive); - - if ((updateFields & MessageUpdateFields.Visibility) == 0) - { - throw new ArgumentException(SR.UpdateMessageVisibilityRequired, "updateFlags"); - } - - Uri messageUri = this.GetIndividualMessageAddress(message.Id); - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, messageUri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.UpdateMessage(cmd.Uri, cmd.ServerTimeoutInSeconds, message.PopReceipt, visibilityTimeout, cnt, ctx); - - if ((updateFields & MessageUpdateFields.Content) != 0) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - QueueRequest.WriteMessageContent(message.GetMessageContentForTransfer(this.EncodeMessage), memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); - - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null, cmd, ctx); - } - - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - GetPopReceiptAndNextVisibleTimeFromResponse(message, resp); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Implementation for the DeleteMessage method. - /// - /// The message ID. - /// The pop receipt value. - /// A object that specifies additional options for the request. - /// A that deletes the queue. - private RESTCommand DeleteMessageImpl(string messageId, string popReceipt, QueueRequestOptions options) - { - Uri messageUri = this.GetIndividualMessageAddress(messageId); - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, messageUri); - - putCmd.ApplyRequestOptions(options); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.DeleteMessage(cmd.Uri, cmd.ServerTimeoutInSeconds, popReceipt, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - - return putCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// The message count. - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand> GetMessagesImpl(int messageCount, TimeSpan? visibilityTimeout, QueueRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetMessages(getCmd.Uri, getCmd.ServerTimeoutInSeconds, messageCount, visibilityTimeout, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - GetMessagesResponse getMessagesResponse = new GetMessagesResponse(cmd.ResponseStream); - - IEnumerable messagesList = new List( - getMessagesResponse.Messages.Select(item => SelectGetMessageResponse(item))); - - return messagesList; - }); - }; - - return getCmd; - } - - /// - /// Implementation for the PeekMessages method. - /// - /// The message count. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand> PeekMessagesImpl(int messageCount, QueueRequestOptions options) - { - RESTCommand> getCmd = new RESTCommand>(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.PeekMessages(getCmd.Uri, getCmd.ServerTimeoutInSeconds, messageCount, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - GetMessagesResponse getMessagesResponse = new GetMessagesResponse(cmd.ResponseStream); - - IEnumerable messagesList = new List( - getMessagesResponse.Messages.Select(item => SelectPeekMessageResponse(item))); - - return messagesList; - }); - }; - - return getCmd; - } - - /// - /// Implementation for the GetPermissions method. - /// - /// The visibility timeout interval. - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetMessageImpl(TimeSpan? visibilityTimeout, QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetMessages(getCmd.Uri, getCmd.ServerTimeoutInSeconds, 1, visibilityTimeout, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - using (IEnumerator enumerator = new GetMessagesResponse(cmd.ResponseStream).Messages.GetEnumerator()) - { - if (enumerator.MoveNext()) - { - return SelectGetMessageResponse(enumerator.Current); - } - } - - return null; - }); - }; - - return getCmd; - } - - /// - /// Implementation for the PeekMessage method. - /// - /// A object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand PeekMessageImpl(QueueRequestOptions options) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.GetMessageRequestAddress()); - - getCmd.ApplyRequestOptions(options); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.PeekMessages(getCmd.Uri, getCmd.ServerTimeoutInSeconds, 1, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - using (IEnumerator enumerator = new GetMessagesResponse(cmd.ResponseStream).Messages.GetEnumerator()) - { - if (enumerator.MoveNext()) - { - return SelectPeekMessageResponse(enumerator.Current); - } - } - - return null; - }); - }; - - return getCmd; - } - - /// - /// Gets the ApproximateMessageCount and metadata from response. - /// - /// The web response. - private void GetMessageCountAndMetadataFromResponse(HttpResponseMessage response) - { - this.Metadata = QueueHttpResponseParsers.GetMetadata(response); - - string count = QueueHttpResponseParsers.GetApproximateMessageCount(response); - this.ApproximateMessageCount = string.IsNullOrEmpty(count) ? (int?)null : int.Parse(count); - } - - /// - /// Update the message pop receipt and next visible time. - /// - /// The message. - /// The web response. - private void GetPopReceiptAndNextVisibleTimeFromResponse(CloudQueueMessage message, HttpResponseMessage webResponse) - { - message.PopReceipt = webResponse.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.PopReceipt); - message.NextVisibleTime = DateTime.Parse( - webResponse.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.NextVisibleTime), - System.Globalization.DateTimeFormatInfo.InvariantInfo, - System.Globalization.DateTimeStyles.AdjustToUniversal); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueClient.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueClient.cs deleted file mode 100644 index 7ce81c06c0a96..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueClient.cs +++ /dev/null @@ -1,293 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Auth; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - - /// - /// Provides a client-side logical representation of the Windows Azure Queue Service. This client is used to configure and execute requests against the Queue Service. - /// - /// The service client encapsulates the base URI for the Queue service. If the service client will be used for authenticated access, it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudQueueClient - { - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - this.authenticationScheme = value; - } - } - - /// - /// Gets the authentication handler used to sign requests. - /// - /// Authentication handler. - internal HttpClientHandler AuthenticationHandler - { - get - { - HttpClientHandler authenticationHandler; - if (this.Credentials.IsSharedKey) - { - authenticationHandler = new SharedKeyAuthenticationHttpHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - authenticationHandler = new NoOpAuthenticationHttpHandler(); - } - - return authenticationHandler; - } - } - - /// - /// Returns a result segment containing a collection of queues. - /// - /// A token returned by a previous listing operation. - /// A result segment of queues. - public IAsyncOperation ListQueuesSegmentedAsync(QueueContinuationToken currentToken) - { - return this.ListQueuesSegmentedAsync(null, QueueListingDetails.None, null, currentToken, null, null); - } - - /// - /// Returns a result segment containing a collection of queues. - /// - /// The queue name prefix. - /// A token returned by a previous listing operation. - /// A result segment of queues. - public IAsyncOperation ListQueuesSegmentedAsync(string prefix, QueueContinuationToken currentToken) - { - return this.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, null, currentToken, null, null); - } - - /// - /// Returns a result segment containing a collection of queues - /// whose names begin with the specified prefix. - /// - /// The queue name prefix. - /// A value that indicates whether to return queue metadata with the listing. - /// A non-negative integer value that indicates the maximum number of results to be returned - /// in the result segment, up to the per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A token returned by a previous listing operation. - /// An object that specifies additional options for the request. - /// An object that represents the context for the current operation. - /// A result segment of queues. - public IAsyncOperation ListQueuesSegmentedAsync(string prefix, QueueListingDetails detailsIncluded, int? maxResults, QueueContinuationToken currentToken, QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => - { - ResultSegment resultSegment = await Executor.ExecuteAsync( - this.ListQueuesImpl(prefix, maxResults, detailsIncluded, modifiedOptions, currentToken), - this.RetryPolicy, - operationContext, - token); - - return new QueueResultSegment(resultSegment.Results, (QueueContinuationToken)resultSegment.ContinuationToken); - }); - } - - /// - /// Core implementation for the ListQueues method. - /// - /// The queue prefix. - /// The details included. - /// The continuation token. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null, the maximum possible number of results will be returned, up to 5000. - /// A that lists the queues. - private RESTCommand> ListQueuesImpl(string prefix, int? maxResults, QueueListingDetails detailsIncluded, QueueRequestOptions options, QueueContinuationToken currentToken) - { - ListingContext listingContext = new ListingContext(prefix, maxResults) - { - Marker = currentToken != null ? currentToken.NextMarker : null - }; - - RESTCommand> getCmd = new RESTCommand>(this.Credentials, this.BaseUri); - - getCmd.ApplyRequestOptions(options); - getCmd.RetrieveResponseStream = true; - getCmd.Handler = this.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.List(cmd.Uri, cmd.ServerTimeoutInSeconds, listingContext, detailsIncluded, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - ListQueuesResponse listQueuesResponse = new ListQueuesResponse(cmd.ResponseStream); - - List queuesList = new List( - listQueuesResponse.Queues.Select(item => new CloudQueue(item.Name, this))); - - QueueContinuationToken continuationToken = null; - if (listQueuesResponse.NextMarker != null) - { - continuationToken = new QueueContinuationToken() - { - NextMarker = listQueuesResponse.NextMarker, - }; - } - - return new ResultSegment(queuesList) - { - ContinuationToken = continuationToken, - }; - }); - }; - - return getCmd; - } - - #region Analytics - - /// - /// Gets the properties of the blob service. - /// - /// The blob service properties. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(null, null); - } - - /// - /// Gets the properties of the blob service. - /// - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. - /// The blob service properties. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync(QueueRequestOptions options, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(options, this); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsync( - this.GetServicePropertiesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - private RESTCommand GetServicePropertiesImpl(QueueRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.GetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - - retCmd.RetrieveResponseStream = true; - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - retCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => QueueHttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)); - }; - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - /// - /// Gets the properties of the blob service. - /// - /// The queue service properties. - /// The blob service properties. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, null, null); - } - - /// - /// Gets the properties of the blob service. - /// - /// The queue service properties. - /// A object that specifies additional options for the request. Specifying null will use the default request options from the associated service client (). - /// An object that represents the context for the current operation. - /// The blob service properties. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties, QueueRequestOptions requestOptions, OperationContext operationContext) - { - QueueRequestOptions modifiedOptions = QueueRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return AsyncInfo.Run(async (token) => await Executor.ExecuteAsyncNullReturn( - this.SetServicePropertiesImpl(properties, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - token)); - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, QueueRequestOptions requestOptions) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(memoryStream); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.ApplyRequestOptions(requestOptions); - retCmd.BuildRequest = (cmd, cnt, ctx) => QueueHttpRequestMessageFactory.SetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - retCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex); - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueMessage.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueMessage.cs deleted file mode 100644 index faa37443f7740..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/CloudQueueMessage.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - using System; - using System.Text; - using System.Runtime.InteropServices.WindowsRuntime; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - /// - /// Represents a message in the Windows Azure Queue service. - /// - public sealed partial class CloudQueueMessage - { - /// - /// Initializes a new instance of the class with the given byte array. - /// - /// The content of the message as a byte array. - /// The new message as a object. - public static CloudQueueMessage CreateCloudQueueMessageFromByteArray([ReadOnlyArray] byte[] content) - { - CloudQueueMessage message = new CloudQueueMessage(null); - message.SetMessageContent(content); - return message; - } - - /// - /// Sets the content of this message. - /// - /// The new message content. - [Windows.Foundation.Metadata.DefaultOverloadAttribute] - public void SetMessageContent([ReadOnlyArray] byte[] content) - { - this.RawString = Convert.ToBase64String(content); - this.MessageType = QueueMessageType.Base64Encoded; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpRequestMessageFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpRequestMessageFactory.cs deleted file mode 100644 index f66248d9aab34..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpRequestMessageFactory.cs +++ /dev/null @@ -1,284 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net.Http; - using System.Text; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static class QueueHttpRequestMessageFactory - { - /// - /// Constructs a web request to create a new queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage Create(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - return HttpRequestMessageFactory.Create(uri, timeout, null, content, operationContext); - } - - /// - /// Constructs a web request to delete the queue and all of the messages within it. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage Delete(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.Delete(uri, timeout, null, content, operationContext); - return request; - } - - /// - /// Generates a web request to return the user-defined metadata for this queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetMetadata(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.GetMetadata(uri, timeout, null, content, operationContext); - return request; - } - - /// - /// Generates a web request to set user-defined metadata for the queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetMetadata(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetMetadata(uri, timeout, null, content, operationContext); - return request; - } - - /// - /// Adds user-defined metadata to the request as one or more name-value pairs. - /// - /// The web request. - /// The user-defined metadata. - public static void AddMetadata(HttpRequestMessage request, IDictionary metadata) - { - HttpRequestMessageFactory.AddMetadata(request, metadata); - } - - /// - /// Adds user-defined metadata to the request as a single name-value pair. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - public static void AddMetadata(HttpRequestMessage request, string name, string value) - { - HttpRequestMessageFactory.AddMetadata(request, name, value); - } - - /// - /// Constructs a web request to return a listing of all queues in this storage account. - /// - /// The absolute URI for the account. - /// The server timeout interval. - /// A set of parameters for the listing operation. - /// Additional details to return with the listing. - /// A web request for the specified operation. - public static HttpRequestMessage List(Uri uri, int? timeout, ListingContext listingContext, QueueListingDetails detailsIncluded, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "list"); - - if (listingContext != null) - { - if (listingContext.Prefix != null) - { - builder.Add("prefix", listingContext.Prefix); - } - - if (listingContext.Marker != null) - { - builder.Add("marker", listingContext.Marker); - } - - if (listingContext.MaxResults != null) - { - builder.Add("maxresults", listingContext.MaxResults.ToString()); - } - } - - if ((detailsIncluded & QueueListingDetails.Metadata) != 0) - { - builder.Add("include", "metadata"); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetAcl(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.GetAcl(uri, timeout, null, content, operationContext); - return request; - } - - /// - /// Constructs a web request to set the ACL for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetAcl(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetAcl(uri, timeout, null, content, operationContext); - return request; - } - - /// - /// Constructs a web request to add a message for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage AddMessage(Uri uri, int? timeout, TimeSpan? timeToLive, TimeSpan? initialVisibilityDelay, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Post, uri, timeout, null, content, operationContext); - - if (timeToLive != null) - { - request.Headers.Add(Constants.QueryConstants.MessageTimeToLive, timeToLive.Value.TotalSeconds.ToString()); - } - - if (initialVisibilityDelay != null) - { - request.Headers.Add(Constants.QueryConstants.VisibilityTimeout, initialVisibilityDelay.Value.TotalSeconds.ToString()); - } - - return request; - } - - /// - /// Constructs a web request to update a message for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage UpdateMessage(Uri uri, int? timeout, string popReceipt, TimeSpan? visibilityTimeout, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - builder.Add(Constants.QueryConstants.PopReceipt, popReceipt); - if (visibilityTimeout != null) - { - builder.Add(Constants.QueryConstants.VisibilityTimeout, visibilityTimeout.Value.TotalSeconds.ToString()); - } - else - { - builder.Add(Constants.QueryConstants.VisibilityTimeout, "0"); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to delete a message for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage DeleteMessage(Uri uri, int? timeout, string popReceipt, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.QueryConstants.PopReceipt, popReceipt); - - HttpRequestMessage request = HttpRequestMessageFactory.Delete(uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to get messages for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetMessages(Uri uri, int? timeout, int numberOfMessages, TimeSpan? visibilityTimeout, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - - builder.Add(Constants.QueryConstants.NumOfMessages, numberOfMessages.ToString()); - - if (visibilityTimeout != null) - { - builder.Add(Constants.QueryConstants.VisibilityTimeout, visibilityTimeout.Value.RoundUpToSeconds().ToString()); - } - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to peek messages for a queue. - /// - /// The absolute URI to the queue. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage PeekMessages(Uri uri, int? timeout, int numberOfMessages, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add(Constants.HeaderConstants.PeekOnly, Constants.HeaderConstants.TrueHeader); - builder.Add(Constants.QueryConstants.NumOfMessages, numberOfMessages.ToString()); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to get the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A HttpRequestMessage to get the service properties. - public static HttpRequestMessage GetServiceProperties(Uri uri, int? timeout, OperationContext operationContext) - { - return HttpRequestMessageFactory.GetServiceProperties(uri, timeout, operationContext); - } - - /// - /// Creates a web request to set the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A web request to set the service properties. - internal static HttpRequestMessage SetServiceProperties(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - return HttpRequestMessageFactory.SetServiceProperties(uri, timeout, content, operationContext); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpResponseParsers.cs deleted file mode 100644 index a52884986958b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Queue/Protocol/QueueHttpResponseParsers.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Queue.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net.Http; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - - internal static partial class QueueHttpResponseParsers - { - /// - /// Gets the approximate message count for the queue. - /// - /// The web response. - /// The approximate count for the queue. - public static string GetApproximateMessageCount(HttpResponseMessage response) - { - return response.Headers.GetHeaderSingleValueOrDefault(Constants.HeaderConstants.LeaseStatus); - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - public static IDictionary GetMetadata(HttpResponseMessage response) - { - return HttpResponseParsers.GetMetadata(response); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/RT.csproj b/microsoft-azure-api/Services/Storage/Lib/RT/RT.csproj deleted file mode 100644 index 81b46bac1be66..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/RT.csproj +++ /dev/null @@ -1,243 +0,0 @@ - - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {42CB7861-70BB-4F34-A815-4355E6EA2589} - winmdobj - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.Storage - en-US - 512 - {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NETFX_CORE;WINDOWS_RT;WINDOWS_RTMD - prompt - 4 - - - true - MSSharedLibKey.snk - true - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_RT;WINDOWS_RTMD;SIGN - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Auth\Auth - - - - Core\Core - - - Core\Auth\Auth - - - Core\Executor\Executor - - - Core\Util\Util - - - - RetryPolicies\RetryPolicies - - - Blob\Blob - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Queue\Protocol\Protocol - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Table - - - Table\Protocol\Protocol - - - Shared\Shared - - - Shared\Protocol\Protocol - - - - - Dependencies\Microsoft.Data.Edm.Portable.dll - - - Dependencies\Microsoft.Data.OData.Portable.dll - - - - Dependencies\System.Spatial.Portable.dll - - - - - - - 11.0 - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Settings.StyleCop b/microsoft-azure-api/Services/Storage/Lib/RT/Settings.StyleCop deleted file mode 100644 index 50892cf448635..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Settings.StyleCop +++ /dev/null @@ -1,315 +0,0 @@ - - - - abc - api - Bool - creds - dequeue - dequeued - Edm - Enum - etag - ETag - Fisma - func - Md - myblob - mycontainer - myfolder - parsable - PostCondition - Retryable - sas - testaccount - testcontainer - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/CappedLengthReadOnlyStream.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/CappedLengthReadOnlyStream.cs deleted file mode 100644 index 9eb78487961c2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/CappedLengthReadOnlyStream.cs +++ /dev/null @@ -1,142 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - using System.IO; - using System.Threading.Tasks; - - internal class CappedLengthReadOnlyStream : Stream - { - private readonly Stream wrappedStream; - private long cappedLength; - - public CappedLengthReadOnlyStream(Stream wrappedStream, long cappedLength) - { - if (!wrappedStream.CanSeek || !wrappedStream.CanRead) - { - throw new NotSupportedException(); - } - - this.wrappedStream = wrappedStream; - this.cappedLength = Math.Min(cappedLength, this.wrappedStream.Length); - } - - public override bool CanRead - { - get - { - return true; - } - } - - public override bool CanSeek - { - get - { - return true; - } - } - - public override bool CanWrite - { - get - { - return false; - } - } - - public override void Flush() - { - throw new NotSupportedException(); - } - - public override long Length - { - get - { - return this.cappedLength; - } - } - - public override long Position - { - get - { - return this.wrappedStream.Position; - } - - set - { - this.wrappedStream.Position = value; - } - } - - public override int Read(byte[] buffer, int offset, int count) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException("count"); - } - - long remainingBytes = this.cappedLength > this.Position ? this.cappedLength - this.Position : 0; - if (count > remainingBytes) - { - count = (int)remainingBytes; - } - - return this.wrappedStream.Read(buffer, offset, count); - } - - public override Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) - { - if (count < 0) - { - throw new ArgumentOutOfRangeException("count"); - } - - long remainingBytes = this.cappedLength > this.Position ? this.cappedLength - this.Position : 0; - if (count > remainingBytes) - { - count = (int)remainingBytes; - } - - return this.wrappedStream.ReadAsync(buffer, offset, count, cancellationToken); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return this.wrappedStream.Seek(offset, origin); - } - - public override void SetLength(long value) - { - if (value < 0 || value > this.Length) - { - throw new ArgumentOutOfRangeException("value"); - } - - this.cappedLength = value; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpClientFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpClientFactory.cs deleted file mode 100644 index b10b7425bedd4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpClientFactory.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.Net.Http; - using System.Net.Http.Headers; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - - internal class HttpClientFactory - { - public static HttpClient BuildHttpClient(StorageCommandBase cmd, OperationContext operationContext) - { - HttpClient client = cmd.Handler != null ? new HttpClient(cmd.Handler, false) : new HttpClient(); - client.DefaultRequestHeaders.ExpectContinue = false; - client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.HeaderConstants.UserAgentProductName, Constants.HeaderConstants.UserAgentProductVersion)); - client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.HeaderConstants.UserAgentComment)); - - client.DefaultRequestHeaders.TryAddWithoutValidation(Constants.HeaderConstants.StorageVersionHeader, Constants.HeaderConstants.TargetStorageVersion); - - if (operationContext != null && operationContext.UserHeaders != null) - { - foreach (string key in operationContext.UserHeaders.Keys) - { - client.DefaultRequestHeaders.Add(key, operationContext.UserHeaders[key]); - } - } - - return client; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpContentFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpContentFactory.cs deleted file mode 100644 index 1550ee292f083..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpContentFactory.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using System; - using System.IO; - using System.Net.Http; - - internal class HttpContentFactory - { - public static HttpContent BuildContentFromStream(Stream stream, long offset, long? length, string md5, RESTCommand cmd, OperationContext operationContext) - { - stream.Seek(offset, SeekOrigin.Begin); - - HttpContent retContent = new RetryableStreamContent(stream); - retContent.Headers.ContentLength = length; - - if (md5 != null) - { - retContent.Headers.ContentMD5 = Convert.FromBase64String(md5); - } - - if (stream is MultiBufferMemoryStream) - { - cmd.StreamToDispose = stream; - } - - return retContent; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpRequestMessageFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpRequestMessageFactory.cs deleted file mode 100644 index a7136794142ea..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpRequestMessageFactory.cs +++ /dev/null @@ -1,268 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Linq; - using System.Net.Http; - using System.Text; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - - internal static class HttpRequestMessageFactory - { - /// - /// Creates the web request. - /// - /// The request Uri. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage CreateRequestMessage(HttpMethod method, Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - if (timeout.HasValue && timeout.Value > 0) - { - builder.Add("timeout", timeout.ToString()); - } - - Uri uriRequest = builder.AddToUri(uri); - - HttpRequestMessage msg = new HttpRequestMessage(method, uriRequest); - msg.Content = content; - - return msg; - } - - /// - /// Creates the specified Uri. - /// - /// The Uri to create. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage Create(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a cloud resource. - /// - /// The absolute URI to the resource. - /// The server timeout interval. - /// An optional query builder to use. - /// A web request to use to perform the operation. - internal static HttpRequestMessage GetAcl(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "acl"); - - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Constructs a web request to set the ACL for a cloud resource. - /// - /// The absolute URI to the resource. - /// The server timeout interval. - /// An optional query builder to use. - /// A web request to use to perform the operation. - internal static HttpRequestMessage SetAcl(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "acl"); - - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Gets the properties. - /// - /// The Uri to query. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage GetProperties(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Head, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Gets the metadata. - /// - /// The blob Uri. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage GetMetadata(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "metadata"); - - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Head, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Sets the metadata. - /// - /// The blob Uri. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage SetMetadata(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - if (builder == null) - { - builder = new UriQueryBuilder(); - } - - builder.Add(Constants.QueryConstants.Component, "metadata"); - - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Adds the metadata. - /// - /// The request. - /// The metadata. - internal static void AddMetadata(HttpRequestMessage request, IDictionary metadata) - { - if (metadata != null) - { - foreach (KeyValuePair entry in metadata) - { - AddMetadata(request, entry.Key, entry.Value); - } - } - } - - /// - /// Adds the metadata. - /// - /// The request. - /// The metadata name. - /// The metadata value. - internal static void AddMetadata(HttpRequestMessage request, string name, string value) - { - CommonUtility.AssertNotNullOrEmpty("value", value); - request.Headers.Add("x-ms-meta-" + name, value); - } - - /// - /// Deletes the specified Uri. - /// - /// The Uri to delete. - /// The timeout. - /// The builder. - /// A web request for performing the operation. - internal static HttpRequestMessage Delete(Uri uri, int? timeout, UriQueryBuilder builder, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = CreateRequestMessage(HttpMethod.Delete, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Creates a web request to get the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A web request to get the service properties. - internal static HttpRequestMessage GetServiceProperties(Uri uri, int? timeout, OperationContext operationContext) - { - UriQueryBuilder builder = GetServiceUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Get, uri, timeout, builder, null /* content */, operationContext); - return request; - } - - /// - /// Creates a web request to set the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A web request to set the service properties. - internal static HttpRequestMessage SetServiceProperties(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - UriQueryBuilder builder = GetServiceUriQueryBuilder(); - builder.Add(Constants.QueryConstants.Component, "properties"); - - HttpRequestMessage request = HttpRequestMessageFactory.CreateRequestMessage(HttpMethod.Put, uri, timeout, builder, content, operationContext); - return request; - } - - /// - /// Generates a query builder for building service requests. - /// - /// A for building service requests. - internal static UriQueryBuilder GetServiceUriQueryBuilder() - { - UriQueryBuilder uriBuilder = new UriQueryBuilder(); - uriBuilder.Add(Constants.QueryConstants.ResourceType, "service"); - return uriBuilder; - } - - public static HttpRequestMessage BuildRequest(HttpMethod method, StorageCommandBase cmd, HttpContent content, OperationContext operationContext) - { - if (cmd.Builder == null) - { - cmd.Builder = new UriQueryBuilder(); - } - - if (cmd.ServerTimeoutInSeconds.HasValue && cmd.ServerTimeoutInSeconds != 0) - { - cmd.Builder.Add("timeout", cmd.ServerTimeoutInSeconds.ToString()); - } - - Uri uriRequest = cmd.Builder.AddToUri(cmd.Uri); - - HttpRequestMessage msg = new HttpRequestMessage(method, uriRequest); - msg.Content = content; - return msg; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpResponseParsers.cs deleted file mode 100644 index 249ab6798ec80..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/HttpResponseParsers.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - using System.Collections.Generic; - using System.Net; - using System.Net.Http; - using System.Net.Http.Headers; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core.Executor; - - internal static partial class HttpResponseParsers - { - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode expectedStatusCode, HttpResponseMessage resp, T retVal, StorageCommandBase cmd, Exception ex) - { - return ProcessExpectedStatusCodeNoException(expectedStatusCode, resp != null ? resp.StatusCode : HttpStatusCode.Unused, retVal, cmd, ex); - } - - internal static T ProcessExpectedStatusCodeNoException(HttpStatusCode[] expectedStatusCodes, HttpResponseMessage resp, T retVal, StorageCommandBase cmd, Exception ex) - { - return ProcessExpectedStatusCodeNoException(expectedStatusCodes, resp != null ? resp.StatusCode : HttpStatusCode.Unused, retVal, cmd, ex); - } - - /// - /// Gets the user-defined metadata. - /// - /// The response from server. - /// A of the metadata. - internal static IDictionary GetMetadata(HttpResponseMessage response) - { - return GetMetadataOrProperties(response, Constants.HeaderConstants.PrefixForStorageMetadata); - } - - /// - /// Gets the metadata or properties. - /// - /// The response from server. - /// The prefix for all the headers. - /// A of the headers with the prefix. - private static IDictionary GetMetadataOrProperties(HttpResponseMessage response, string prefix) - { - IDictionary nameValues = new Dictionary(); - HttpResponseHeaders headers = response.Headers; - int prefixLength = prefix.Length; - - foreach (KeyValuePair> header in headers) - { - if (header.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - nameValues[header.Key.Substring(prefixLength)] = string.Join(",", header.Value); - } - } - - return nameValues; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RequestMessageExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RequestMessageExtensions.cs deleted file mode 100644 index 86d65eed19980..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RequestMessageExtensions.cs +++ /dev/null @@ -1,187 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System; - using System.Net.Http; - using System.Net.Http.Headers; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Util; - - internal static class RequestMessageExtensions - { - /// - /// Adds the lease id. - /// - /// The request. - /// The lease id. - internal static void AddLeaseId(this HttpRequestMessage request, string leaseId) - { - if (leaseId != null) - { - request.AddOptionalHeader("x-ms-lease-id", leaseId); - } - } - - /// - /// Adds the optional header. - /// - /// The web request. - /// The metadata name. - /// The metadata value. - internal static void AddOptionalHeader(this HttpRequestMessage request, string name, string value) - { - if (!string.IsNullOrEmpty(value)) - { - request.Headers.Add(name, value); - } - } - - /// - /// Adds an optional header to a request. - /// - /// The web request. - /// The header name. - /// The header value. - internal static void AddOptionalHeader(this HttpRequestMessage request, string name, int? value) - { - if (value.HasValue) - { - request.Headers.Add(name, value.Value.ToString()); - } - } - - /// - /// Adds an optional header to a request. - /// - /// The web request. - /// The header name. - /// The header value. - internal static void AddOptionalHeader(this HttpRequestMessage request, string name, long? value) - { - if (value.HasValue) - { - request.Headers.Add(name, value.Value.ToString()); - } - } - - /// - /// Applies the lease condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyLeaseId(this HttpRequestMessage request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.LeaseId)) - { - request.Headers.Add(Constants.HeaderConstants.LeaseIdHeader, accessCondition.LeaseId); - } - } - } - - /// - /// Applies the sequence number condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplySequenceNumberCondition(this HttpRequestMessage request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberLEHeader, accessCondition.IfSequenceNumberLessThanOrEqual); - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberLTHeader, accessCondition.IfSequenceNumberLessThan); - request.AddOptionalHeader(Constants.HeaderConstants.IfSequenceNumberEqHeader, accessCondition.IfSequenceNumberEqual); - } - } - - /// - /// Applies the condition to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyAccessCondition(this HttpRequestMessage request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - request.Headers.IfMatch.Add(EntityTagHeaderValue.Parse(accessCondition.IfMatchETag)); - } - - if (!string.IsNullOrEmpty(accessCondition.IfNoneMatchETag)) - { - if (accessCondition.IfNoneMatchETag.Equals(EntityTagHeaderValue.Any.ToString(), StringComparison.OrdinalIgnoreCase)) - { - request.Headers.IfNoneMatch.Add(EntityTagHeaderValue.Any); - } - else - { - request.Headers.IfNoneMatch.Add(EntityTagHeaderValue.Parse(accessCondition.IfNoneMatchETag)); - } - } - - request.Headers.IfModifiedSince = accessCondition.IfModifiedSinceTime; - request.Headers.IfUnmodifiedSince = accessCondition.IfNotModifiedSinceTime; - - request.ApplyLeaseId(accessCondition); - } - } - - /// - /// Applies the condition for a source blob to the web request. - /// - /// The request to be modified. - /// Access condition to be added to the request. - internal static void ApplyAccessConditionToSource(this HttpRequestMessage request, AccessCondition accessCondition) - { - if (accessCondition != null) - { - if (!string.IsNullOrEmpty(accessCondition.IfMatchETag)) - { - request.Headers.Add(Constants.HeaderConstants.SourceIfMatchHeader, accessCondition.IfMatchETag); - } - - if (!string.IsNullOrEmpty(accessCondition.IfNoneMatchETag)) - { - request.Headers.Add(Constants.HeaderConstants.SourceIfNoneMatchHeader, accessCondition.IfNoneMatchETag); - } - - if (accessCondition.IfModifiedSinceTime.HasValue) - { - request.Headers.Add( - Constants.HeaderConstants.SourceIfModifiedSinceHeader, - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfModifiedSinceTime.Value)); - } - - if (accessCondition.IfNotModifiedSinceTime.HasValue) - { - request.Headers.Add( - Constants.HeaderConstants.SourceIfUnmodifiedSinceHeader, - HttpWebUtility.ConvertDateTimeToHttpString(accessCondition.IfNotModifiedSinceTime.Value)); - } - - if (!string.IsNullOrEmpty(accessCondition.LeaseId)) - { - throw new InvalidOperationException(SR.LeaseConditionOnSource); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RetryableStreamContent.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RetryableStreamContent.cs deleted file mode 100644 index 4720c9e78118c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Shared/Protocol/RetryableStreamContent.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.IO; - using System.Net.Http; - - internal class RetryableStreamContent : StreamContent - { - /// - /// Creates a new instance of the RetryableStreamContent class. - /// - /// The content used to initialize the RetryableStreamContent. - public RetryableStreamContent(Stream content) - : base(content) - { - } - - /// - /// Creates a new instance of the RetryableStreamContent class. - /// - /// The content used to initialize the RetryableStreamContent. - /// The size, in bytes, of the buffer for the RetryableStreamContent. - public RetryableStreamContent(Stream content, int bufferSize) - : base(content, bufferSize) - { - } - - /// - /// Ignores the request and does not call base.Dispose. - /// - /// Not used. - protected override void Dispose(bool disposing) - { - // This method does not call base.Dispose, which will go ahead - // and dispose the underlying stream as well. However, that would - // mean each retry by Executor needing a new stream to be re-created - // and also disposing client's stream without their knowledge. - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTable.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTable.cs deleted file mode 100644 index 0a3f8ede6c1ec..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTable.cs +++ /dev/null @@ -1,462 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Net; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Windows.Foundation; - - /// - /// Represents a Windows Azure Table. - /// - public sealed partial class CloudTable - { - #region TableOperation Execute Methods - /// - /// Executes the operation on a table. - /// - /// A object that represents the operation to perform. - /// A containing the result of executing the operation on the table. - public IAsyncOperation ExecuteAsync(TableOperation operation) - { - return this.ExecuteAsync(operation, null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Executes the operation on a table, using the specified and . - /// - /// A object that represents the operation to perform. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A containing the result of executing the operation on the table. - public IAsyncOperation ExecuteAsync(TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("operation", operation); - - return operation.ExecuteAsync(this.ServiceClient, this.Name, requestOptions, operationContext); - } - #endregion - - #region TableBatchOperation Execute Methods - /// - /// Executes a batch operation on a table as an atomic operation. - /// - /// The object representing the operations to execute on the table. - /// An enumerable collection of objects that contains the results, in order, of each operation in the on the table. - public IAsyncOperation> ExecuteBatchAsync(TableBatchOperation batch) - { - return this.ExecuteBatchAsync(batch, null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Executes a batch operation on a table as an atomic operation, using the specified and . - /// - /// The object representing the operations to execute on the table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An enumerable collection of objects that contains the results, in order, of each operation in the on the table. - public IAsyncOperation> ExecuteBatchAsync(TableBatchOperation batch, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("batch", batch); - return batch.ExecuteAsync(this.ServiceClient, this.Name, requestOptions, operationContext); - } - #endregion - - #region TableQuery Execute Methods - internal IEnumerable ExecuteQuery(TableQuery query) - { - return this.ExecuteQuery(query, null /* RequestOptions */, null /* OperationContext */); - } - - internal IEnumerable ExecuteQuery(TableQuery query, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("query", query); - return query.Execute(this.ServiceClient, this.Name, requestOptions, operationContext); - } - - /// - /// Executes a query in segmented mode with the specified continuation token. - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object containing the results of executing the query. - public IAsyncOperation ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token) - { - return this.ExecuteQuerySegmentedAsync(query, token, null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Executes a query in segmented mode with the specified continuation token, , and . - /// - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A object containing the results of executing the query. - public IAsyncOperation ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("query", query); - return query.ExecuteQuerySegmentedAsync(token, this.ServiceClient, this.Name, requestOptions, operationContext); - } - - #endregion - - #region Create - - /// - /// Creates the Table. - /// - /// An that represents an asynchronous action. - public IAsyncAction CreateAsync() - { - return this.CreateAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Creates the Table. - /// - /// A object that specifies additional options for the request. - /// An object for tracking the current operation. - /// An that represents an asynchronous action. - public IAsyncAction CreateAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Insert); - operation.IsTableEntity = true; - - return this.ServiceClient.ExecuteAsync(TableConstants.TableServiceTablesName, operation, requestOptions, operationContext).AsTask().AsAsyncAction(); - } - - #endregion - - #region CreateIfNotExists - - /// - /// Creates the table if it does not already exist. - /// - /// true if table was created; otherwise, false. - public IAsyncOperation CreateIfNotExistsAsync() - { - return this.CreateIfNotExistsAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Creates the table if it does not already exist. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if table was created; otherwise, false. - public IAsyncOperation CreateIfNotExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (cancellationToken) => - { - if (await this.ExistsAsync(requestOptions, operationContext).AsTask(cancellationToken)) - { - return false; - } - else - { - try - { - await this.CreateAsync(requestOptions, operationContext).AsTask(cancellationToken); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.Conflict) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == TableErrorCodeStrings.TableAlreadyExists)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } - }); - } - #endregion - - #region Delete - - /// - /// Deletes the Table. - /// - /// An that represents an asynchronous action. - public IAsyncAction DeleteAsync() - { - return this.DeleteAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Deletes the Table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An that represents an asynchronous action. - public IAsyncAction DeleteAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Delete); - operation.IsTableEntity = true; - - return this.ServiceClient.ExecuteAsync(TableConstants.TableServiceTablesName, operation, requestOptions, operationContext).AsTask().AsAsyncAction(); - } - #endregion - - #region DeleteIfExists - - /// - /// Deletes the table if it already exists. - /// - /// true if the table already existed and was deleted; otherwise, false. - public IAsyncOperation DeleteIfExistsAsync() - { - return this.DeleteIfExistsAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Deletes the table if it already exists. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if the table already existed and was deleted; otherwise, false. - public IAsyncOperation DeleteIfExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (cancellationToken) => - { - if (!await this.ExistsAsync(requestOptions, operationContext).AsTask(cancellationToken)) - { - return false; - } - else - { - try - { - await this.DeleteAsync(requestOptions, operationContext).AsTask(cancellationToken); - return true; - } - catch (Exception) - { - if (operationContext.LastResult.HttpStatusCode == (int)HttpStatusCode.NotFound) - { - StorageExtendedErrorInformation extendedInfo = operationContext.LastResult.ExtendedErrorInformation; - if ((extendedInfo == null) || - (extendedInfo.ErrorCode == TableErrorCodeStrings.TableNotFound)) - { - return false; - } - else - { - throw; - } - } - else - { - throw; - } - } - } - }); - } - #endregion - - #region Exists - /// - /// Creates the Table. - /// - /// true if the table was created successfully; otherwise, false. - public IAsyncOperation ExistsAsync() - { - return this.ExistsAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Creates the Table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// true if the table was created successfully; otherwise, false. - public IAsyncOperation ExistsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - DynamicTableEntity tblEntity = new DynamicTableEntity(); - tblEntity.Properties.Add(TableConstants.TableName, new EntityProperty(this.Name)); - TableOperation operation = new TableOperation(tblEntity, TableOperationType.Retrieve); - operation.IsTableEntity = true; - - return AsyncInfo.Run(async (cancellationToken) => - { - TableResult res = await this.ServiceClient.ExecuteAsync(TableConstants.TableServiceTablesName, operation, requestOptions, operationContext).AsTask(cancellationToken); - - // Only other option is not found, other status codes will throw prior to this. - return res.HttpStatusCode == (int)HttpStatusCode.OK; - }); - } - #endregion - - #region Permissions - /// - /// Sets permissions for the Table. - /// - /// The permissions to apply to the Table. - /// An that represents an asynchronous action. - public IAsyncAction SetPermissionsAsync(TablePermissions permissions) - { - return this.SetPermissionsAsync(permissions, null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Sets permissions for the Table. - /// - /// The permissions to apply to the Table. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An that represents an asynchronous action. - public IAsyncAction SetPermissionsAsync(TablePermissions permissions, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsyncNullReturn( - this.SetPermissionsImpl(permissions, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - /// - /// Implementation for the SetPermissions method. - /// - /// The permissions to set. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// A that sets the permissions. - private RESTCommand SetPermissionsImpl(TablePermissions acl, TableRequestOptions requestOptions) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - TableRequest.WriteSharedAccessIdentifiers(acl.SharedAccessPolicies, memoryStream); - - RESTCommand putCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - putCmd.ApplyRequestOptions(requestOptions); - putCmd.Handler = this.ServiceClient.AuthenticationHandler; - putCmd.BuildClient = HttpClientFactory.BuildHttpClient; - putCmd.BuildRequest = (cmd, cnt, ctx) => TableHttpRequestMessageFactory.SetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - putCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => - { - HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.NoContent, resp, NullType.Value, cmd, ex); - return NullType.Value; - }; - - return putCmd; - } - - /// - /// Gets the permissions settings for the Table. - /// - /// The Table's permissions. - public IAsyncOperation GetPermissionsAsync() - { - return this.GetPermissionsAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Gets the permissions settings for the Table. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The Table's permissions. - public IAsyncOperation GetPermissionsAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this.ServiceClient); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsync( - this.GetPermissionsImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - /// - /// Implementation for the GetPermissions method. - /// - /// An object that specifies additional options for the request. - /// A that gets the permissions. - private RESTCommand GetPermissionsImpl(TableRequestOptions requestOptions) - { - RESTCommand getCmd = new RESTCommand(this.ServiceClient.Credentials, this.Uri); - - getCmd.ApplyRequestOptions(requestOptions); - getCmd.Handler = this.ServiceClient.AuthenticationHandler; - getCmd.BuildClient = HttpClientFactory.BuildHttpClient; - getCmd.RetrieveResponseStream = true; - getCmd.BuildRequest = (cmd, cnt, ctx) => TableHttpRequestMessageFactory.GetAcl(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - getCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - getCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => - { - TablePermissions TableAcl = new TablePermissions(); - HttpResponseParsers.ReadSharedAccessIdentifiers(TableAcl.SharedAccessPolicies, new TableAccessPolicyResponse(cmd.ResponseStream)); - return TableAcl; - }); - }; - - return getCmd; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTableClient.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTableClient.cs deleted file mode 100644 index b5435d06190b9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/CloudTableClient.cs +++ /dev/null @@ -1,301 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Auth.Protocol; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Queue.Protocol; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - - /// - /// Provides a client-side logical representation of the Windows Azure Table Service. This client is used to configure and execute requests against the Table Service. - /// - /// The service client encapsulates the base URI for the Table service. If the service client will be used for authenticated access, it also encapsulates the credentials for accessing the storage account. - public sealed partial class CloudTableClient - { - /// - /// Gets or sets the authentication scheme to use to sign HTTP requests. - /// - public AuthenticationScheme AuthenticationScheme - { - get - { - return this.authenticationScheme; - } - - set - { - this.authenticationScheme = value; - } - } - - /// - /// Gets the authentication handler used to sign HTTP requests. - /// - /// The authentication handler. - internal HttpClientHandler AuthenticationHandler - { - get - { - HttpClientHandler authenticationHandler; - if (this.Credentials.IsSharedKey) - { - authenticationHandler = new SharedKeyAuthenticationHttpHandler( - this.GetCanonicalizer(), - this.Credentials, - this.Credentials.AccountName); - } - else - { - authenticationHandler = new NoOpAuthenticationHttpHandler(); - } - - return authenticationHandler; - } - } - - #region TableOperation Execute Methods - internal IAsyncOperation ExecuteAsync(string tableName, TableOperation operation, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("operation", operation); - - return operation.ExecuteAsync(this, tableName, requestOptions, operationContext); - } - #endregion - - #region TableQuery Execute Methods - internal IAsyncOperation ExecuteQuerySegmentedAsync(string tableName, TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("query", query); - return query.ExecuteQuerySegmentedAsync(token, this, tableName, requestOptions, operationContext); - } - #endregion - - #region List Tables - internal IEnumerable ListTables() - { - return this.ListTables(null); - } - - internal IEnumerable ListTables(string prefix) - { - return this.ListTables(prefix, null /* RequestOptions */, null /* OperationContext */); - } - - internal IEnumerable ListTables(string prefix, TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - - return this.GenerateListTablesQuery(prefix, null).Execute(this, TableConstants.TableServiceTablesName, requestOptions, operationContext).Select( - tbl => new CloudTable(tbl.Properties[TableConstants.TableName].StringValue, this)); - } - - /// - /// Returns a collection of table items. - /// - /// A token returned by a previous listing operation. - /// The result segment containing the collection of tables. - public IAsyncOperation ListTablesSegmentedAsync(TableContinuationToken currentToken) - { - return this.ListTablesSegmentedAsync(null, null /* maxResults */, currentToken, null /* TableRequestOptions */, null /* OperationContext */); - } - - /// - /// Returns a result segment containing a collection of table items beginning with the specified prefix. - /// - /// The table name prefix. - /// A token returned by a previous listing operation. - /// The result segment containing the collection of tables. - public IAsyncOperation ListTablesSegmentedAsync(string prefix, TableContinuationToken currentToken) - { - return this.ListTablesSegmentedAsync(prefix, null /* maxResults */, currentToken, null /* TableRequestOptions */, null /* OperationContext */); - } - - /// - /// Returns a result segment containing a collection of tables beginning with the specified prefix. - /// - /// The table name prefix. - /// A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the - /// per-operation limit of 5000. If this value is null the maximum possible number of results will be returned, up to 5000. - /// A token returned by a previous listing operation. - /// A object that specifies additional options for the request. - /// An object that provides information on how the operation executed. - /// The result segment containing the collection of tables. - public IAsyncOperation ListTablesSegmentedAsync(string prefix, int? maxResults, TableContinuationToken currentToken, TableRequestOptions requestOptions, OperationContext operationContext) - { - requestOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - - TableQuery query = this.GenerateListTablesQuery(prefix, maxResults); - return AsyncInfo.Run(async (cancellationToken) => - { - TableQuerySegment seg = await this.ExecuteQuerySegmentedAsync(TableConstants.TableServiceTablesName, query, currentToken, requestOptions, operationContext).AsTask(cancellationToken); - - TableResultSegment retSegment = new TableResultSegment(seg.Results.Select(tbl => new CloudTable(tbl.Properties[TableConstants.TableName].StringValue, this)).ToList()); - retSegment.ContinuationToken = seg.ContinuationToken; - return retSegment; - }); - } - - private TableQuery GenerateListTablesQuery(string prefix, int? maxResults) - { - TableQuery query = new TableQuery(); - - if (!string.IsNullOrEmpty(prefix)) - { - // Append Max char to end '{' is 1 + 'z' in AsciiTable - string uppperBound = prefix + '{'; - - query = query.Where(TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition(TableConstants.TableName, QueryComparisons.GreaterThanOrEqual, prefix), - TableOperators.And, - TableQuery.GenerateFilterCondition(TableConstants.TableName, QueryComparisons.LessThan, uppperBound))); - } - - if (maxResults.HasValue) - { - query = query.Take(maxResults.Value); - } - - return query; - } - #endregion - - #region Analytics - - /// - /// Gets the properties of the table service. - /// - /// The table service properties as a object. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync() - { - return this.GetServicePropertiesAsync(null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Gets the properties of the table service. - /// - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// The table service properties as a object. - [DoesServiceRequest] - public IAsyncOperation GetServicePropertiesAsync(TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsync( - this.GetServicePropertiesImpl(modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private RESTCommand GetServicePropertiesImpl(TableRequestOptions requestOptions) - { - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.BuildRequest = (cmd, cnt, ctx) => TableHttpRequestMessageFactory.GetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - - retCmd.RetrieveResponseStream = true; - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); - - retCmd.PostProcessResponse = (cmd, resp, ctx) => - { - return Task.Factory.StartNew(() => HttpResponseParsers.ReadServiceProperties(cmd.ResponseStream)); - }; - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - /// - /// Gets the properties of the table service. - /// - /// The table service properties. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties) - { - return this.SetServicePropertiesAsync(properties, null /* RequestOptions */, null /* OperationContext */); - } - - /// - /// Gets the properties of the table service. - /// - /// The table service properties. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// An that represents an asynchronous action. - [DoesServiceRequest] - public IAsyncAction SetServicePropertiesAsync(ServiceProperties properties, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, this); - operationContext = operationContext ?? new OperationContext(); - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsyncNullReturn( - this.SetServicePropertiesImpl(properties, modifiedOptions), - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private RESTCommand SetServicePropertiesImpl(ServiceProperties properties, TableRequestOptions requestOptions) - { - MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB)); - try - { - properties.WriteServiceProperties(memoryStream); - } - catch (InvalidOperationException invalidOpException) - { - throw new ArgumentException(invalidOpException.Message, "properties"); - } - - RESTCommand retCmd = new RESTCommand(this.Credentials, this.BaseUri); - retCmd.ApplyRequestOptions(requestOptions); - retCmd.BuildRequest = (cmd, cnt, ctx) => TableHttpRequestMessageFactory.SetServiceProperties(cmd.Uri, cmd.ServerTimeoutInSeconds, cnt, ctx); - retCmd.BuildContent = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, null /* md5 */, cmd, ctx); - retCmd.Handler = this.AuthenticationHandler; - retCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retCmd.PreProcessResponse = - (cmd, resp, ex, ctx) => - HttpResponseParsers.ProcessExpectedStatusCodeNoException(System.Net.HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex); - - retCmd.ApplyRequestOptions(requestOptions); - return retCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpRequestAdapterMessage.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpRequestAdapterMessage.cs deleted file mode 100644 index 12d1075306e58..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpRequestAdapterMessage.cs +++ /dev/null @@ -1,134 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Net.Http; - - internal class HttpRequestAdapterMessage : IODataRequestMessage, IDisposable - { - public HttpRequestMessage GetPopulatedMessage() - { - this.msg.Content = this.content; - this.outStr.Seek(0, SeekOrigin.Begin); - return this.msg; - } - - // Summary: - // Initializes a new instance of the System.Net.Http.HttpRequestMessage class. - public HttpRequestAdapterMessage(HttpRequestMessage msg, IBufferManager bufferManager, int bufferSize) - { - this.msg = msg; - this.outStr = new MultiBufferMemoryStream(bufferManager, bufferSize); - this.content = new StreamContent(this.outStr); - } - - private StreamContent content = null; - - private HttpRequestMessage msg = null; - - private MultiBufferMemoryStream outStr = null; - - public string GetHeader(string headerName) - { - switch (headerName) - { - case "Content-Type": - return this.content.Headers.ContentType != null ? this.content.Headers.ContentType.ToString() : null; - case "Content-Range": - return this.content.Headers.ContentRange != null ? this.content.Headers.ContentRange.ToString() : null; - case "Content-MD5": - return this.content.Headers.ContentMD5 != null ? Convert.ToBase64String(this.content.Headers.ContentMD5) : null; - case "Content-Location": - return this.content.Headers.ContentLocation != null ? this.content.Headers.ContentLocation.ToString() : null; - case "Content-Length": - return this.content.Headers.ContentLength != null ? this.content.Headers.ContentLength.ToString() : null; - case "Content-Language": - return this.content.Headers.ContentLanguage != null ? this.content.Headers.ContentLanguage.ToString() : null; - case "Content-Encoding": - return this.content.Headers.ContentEncoding != null ? this.content.Headers.ContentEncoding.ToString() : null; - case "Content-Disposition": - return this.content.Headers.ContentDisposition != null ? this.content.Headers.ContentDisposition.ToString() : null; - default: - return this.content.Headers.Contains(headerName) ? this.content.Headers.GetValues(headerName).First() : null; - } - } - - public Stream GetStream() - { - return this.outStr; - } - - public System.Collections.Generic.IEnumerable> Headers - { - get { return this.msg.Headers.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.FirstOrDefault())); } - } - - public string Method - { - get - { - return this.msg.Method.Method; - } - - set - { - this.msg.Method = new HttpMethod(value); - } - } - - public void SetHeader(string headerName, string headerValue) - { - if (headerName.StartsWith("Content-")) - { - this.content.Headers.Add(headerName, headerValue); - } - else - { - this.msg.Headers.Add(headerName, headerValue); - } - } - - public Uri Url - { - get - { - return this.msg.RequestUri; - } - - set - { - this.msg.RequestUri = value; - } - } - - [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Justification = "Members used after adaptermessage is disposed")] - public void Dispose() - { - this.msg = null; - this.outStr = null; - this.content = null; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpResponseAdapterMessage.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpResponseAdapterMessage.cs deleted file mode 100644 index 11161457d0d53..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/HttpResponseAdapterMessage.cs +++ /dev/null @@ -1,98 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net.Http; - using System.Text; - using System.Threading.Tasks; - using Microsoft.Data.OData; - - internal class HttpResponseAdapterMessage : IODataResponseMessage - { - private HttpResponseMessage resp = null; - private Stream str = null; - - public HttpResponseAdapterMessage(HttpResponseMessage resp, Stream str) - { - this.resp = resp; - this.str = str; - } - - public Task GetStreamAsync() - { - return Task.Factory.StartNew(() => this.str); - } - - public string GetHeader(string headerName) - { - switch (headerName) - { - case "Content-Type": - return this.resp.Content.Headers.ContentType != null ? this.resp.Content.Headers.ContentType.ToString() : null; - case "Content-Range": - return this.resp.Content.Headers.ContentRange != null ? this.resp.Content.Headers.ContentRange.ToString() : null; - case "Content-MD5": - return this.resp.Content.Headers.ContentMD5 != null ? Convert.ToBase64String(this.resp.Content.Headers.ContentMD5) : null; - case "Content-Location": - return this.resp.Content.Headers.ContentLocation != null ? this.resp.Content.Headers.ContentLocation.ToString() : null; - case "Content-Length": - return this.resp.Content.Headers.ContentLength != null ? this.resp.Content.Headers.ContentLength.ToString() : null; - case "Content-Language": - return this.resp.Content.Headers.ContentLanguage != null ? this.resp.Content.Headers.ContentLanguage.ToString() : null; - case "Content-Encoding": - return this.resp.Content.Headers.ContentEncoding != null ? this.resp.Content.Headers.ContentEncoding.ToString() : null; - case "Content-Disposition": - return this.resp.Content.Headers.ContentDisposition != null ? this.resp.Content.Headers.ContentDisposition.ToString() : null; - default: - return this.resp.Content.Headers.Contains(headerName) ? this.resp.Content.Headers.GetValues(headerName).First() : null; - } - } - - public Stream GetStream() - { - return this.str; - } - - public IEnumerable> Headers - { - get { return this.resp.Headers.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.FirstOrDefault())); } - } - - public void SetHeader(string headerName, string headerValue) - { - throw new NotImplementedException(); - } - - public int StatusCode - { - get - { - return (int)this.resp.StatusCode; - } - - set - { - throw new NotSupportedException(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableHttpRequestMessageFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableHttpRequestMessageFactory.cs deleted file mode 100644 index d49a392b4048a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableHttpRequestMessageFactory.cs +++ /dev/null @@ -1,98 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Net.Http; - - internal static class TableHttpRequestMessageFactory - { - /// - /// Constructs a web request to create a new table. - /// - /// The absolute URI to the table. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage Create(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.Create(uri, timeout, null /* builder */, content, operationContext); - return request; - } - - /// - /// Constructs a web request to delete the table - /// - /// The absolute URI to the table. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage Delete(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.Delete(uri, timeout, null /* builder */, content, operationContext); - return request; - } - - /// - /// Constructs a web request to return the ACL for a table. - /// - /// The absolute URI to the table. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage GetAcl(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.GetAcl(uri, timeout, null /* builder */, content, operationContext); - return request; - } - - /// - /// Constructs a web request to set the ACL for a table. - /// - /// The absolute URI to the table. - /// The server timeout interval. - /// A web request to use to perform the operation. - public static HttpRequestMessage SetAcl(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetAcl(uri, timeout, null /* builder */, content, operationContext); - return request; - } - - /// - /// Constructs a web request to get the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A HttpRequestMessage to get the service properties. - public static HttpRequestMessage GetServiceProperties(Uri uri, int? timeout, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.GetServiceProperties(uri, timeout, operationContext); - return request; - } - - /// - /// Creates a web request to set the properties of the service. - /// - /// The absolute URI to the service. - /// The server timeout interval. - /// A web request to set the service properties. - internal static HttpRequestMessage SetServiceProperties(Uri uri, int? timeout, HttpContent content, OperationContext operationContext) - { - HttpRequestMessage request = HttpRequestMessageFactory.SetServiceProperties(uri, timeout, content, operationContext); - return request; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpRequestFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpRequestFactory.cs deleted file mode 100644 index ceee8e3447359..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpRequestFactory.cs +++ /dev/null @@ -1,210 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - - internal class TableOperationHttpRequestMessageFactory - { - internal static HttpRequestMessage BuildRequestCore(Uri uri, HttpMethod method, int? timeout, OperationContext ctx) - { - Uri uriRequest = uri; - if (timeout != null && timeout != 0) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add("timeout", timeout.ToString()); - uriRequest = builder.AddToUri(uri); - } - - HttpRequestMessage msg = new HttpRequestMessage(method, uriRequest); - msg.Headers.Add("Accept", "application/atom+xml,application/xml"); - msg.Headers.Add("Accept-Charset", "UTF-8"); - msg.Headers.Add("MaxDataServiceVersion", "2.0;NetFx"); - - return msg; - } - - internal static HttpRequestMessage BuildRequestForTableQuery(Uri uri, int? timeout, OperationContext ctx) - { - HttpRequestMessage msg = BuildRequestCore(uri, HttpMethod.Get, timeout, ctx); - - return msg; - } - - internal static HttpRequestMessage BuildRequestForTableOperation(RESTCommand cmd, int? timeout, TableOperation operation, CloudTableClient client, OperationContext ctx) - { - HttpRequestMessage msg = BuildRequestCore(cmd.Uri, operation.HttpMethod, timeout, ctx); - - if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) - { - // post tunnelling - msg.Headers.Add("X-HTTP-Method", "MERGE"); - } - - // etag - if (operation.OperationType == TableOperationType.Delete || - operation.OperationType == TableOperationType.Replace || - operation.OperationType == TableOperationType.Merge) - { - msg.Headers.Add("If-Match", operation.Entity.ETag); - } - - if (operation.OperationType == TableOperationType.Insert || - operation.OperationType == TableOperationType.Merge || - operation.OperationType == TableOperationType.InsertOrMerge || - operation.OperationType == TableOperationType.InsertOrReplace || - operation.OperationType == TableOperationType.Replace) - { - // create the writer, indent for readability of the examples. - ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() - { - CheckCharacters = false, // sets this flag on the XmlWriter for ATOM - Version = ODataVersion.V2 // set the Odata version to use when writing the entry - }; - - HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, (int)Constants.KB); - cmd.StreamToDispose = adapterMsg.GetStream(); - - ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); - ODataWriter writer = odataWriter.CreateODataEntryWriter(); - WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer); - - return adapterMsg.GetPopulatedMessage(); - } - - return msg; - } - - internal static HttpRequestMessage BuildRequestForTableBatchOperation(RESTCommand cmd, int? timeout, Uri baseUri, string tableName, TableBatchOperation batch, CloudTableClient client, OperationContext ctx) - { - HttpRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToUri(cmd.Uri, "$batch"), HttpMethod.Post, timeout, ctx); - - // create the writer, indent for readability of the examples. - ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() - { - CheckCharacters = false, // sets this flag on the XmlWriter for ATOM - Version = ODataVersion.V2 // set the Odata version to use when writing the entry - }; - - HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, 64 * (int)Constants.KB); - cmd.StreamToDispose = adapterMsg.GetStream(); - - // Start Batch - ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); - ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter(); - batchWriter.WriteStartBatch(); - - bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; - - // Query operations should not be inside changeset in payload - if (!isQuery) - { - // Start Operation - batchWriter.WriteStartChangeset(); - batchWriter.Flush(); - } - - foreach (TableOperation operation in batch) - { - string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method; - - ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(baseUri, tableName)); - - // etag - if (operation.OperationType == TableOperationType.Delete || - operation.OperationType == TableOperationType.Replace || - operation.OperationType == TableOperationType.Merge) - { - mimePartMsg.SetHeader("If-Match", operation.Entity.ETag); - } - - if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) - { - using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings)) - { - // Write entity - ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter(); - WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter); - } - } - } - - if (!isQuery) - { - // End Operation - batchWriter.WriteEndChangeset(); - } - - // End Batch - batchWriter.WriteEndBatch(); - batchWriter.Flush(); - - return adapterMsg.GetPopulatedMessage(); - } - - private static void WriteOdataEntity(ITableEntity entity, TableOperationType operationType, OperationContext ctx, ODataWriter writer) - { - ODataEntry entry = new ODataEntry() - { - Properties = GetPropertiesWithKeys(entity, ctx) - }; - - if (operationType != TableOperationType.Insert && operationType != TableOperationType.Retrieve) - { - entry.ETag = entity.ETag; - } - - writer.WriteStart(entry); - writer.WriteEnd(); - writer.Flush(); - } - - #region TableEntity Serialization Helpers - - internal static List GetPropertiesFromDictionary(IDictionary properties) - { - return properties.Select(kvp => new ODataProperty() { Name = kvp.Key, Value = kvp.Value.PropertyAsObject }).ToList(); - } - - internal static List GetPropertiesWithKeys(ITableEntity entity, OperationContext operationContext) - { - List retProps = GetPropertiesFromDictionary(entity.WriteEntity(operationContext)); - - if (entity.PartitionKey != null) - { - retProps.Add(new ODataProperty() { Name = TableConstants.PartitionKey, Value = entity.PartitionKey }); - } - - if (entity.RowKey != null) - { - retProps.Add(new ODataProperty() { Name = TableConstants.RowKey, Value = entity.RowKey }); - } - - return retProps; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpResponseParsers.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpResponseParsers.cs deleted file mode 100644 index 8489fe21c2286..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/Protocol/TableOperationHttpResponseParsers.cs +++ /dev/null @@ -1,488 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table.Protocol -{ - using Microsoft.Data.OData; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Net; - using System.Net.Http; - using System.Threading.Tasks; - - internal class TableOperationHttpResponseParsers - { - internal static TableResult TableOperationPreProcess(TableResult result, TableOperation operation, HttpResponseMessage resp, Exception ex, StorageCommandBase cmd, OperationContext ctx) - { - result.HttpStatusCode = (int)resp.StatusCode; - - if (operation.OperationType == TableOperationType.Retrieve) - { - if (resp.StatusCode != HttpStatusCode.OK && resp.StatusCode != HttpStatusCode.NotFound) - { - throw new StorageException(cmd.CurrentResult, string.Format(SR.UnexpectedResponseCode, HttpStatusCode.OK.ToString() + " or " + HttpStatusCode.NotFound.ToString(), resp.StatusCode.ToString()), null); - } - } - else - { - if (ex != null) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - else if (operation.OperationType == TableOperationType.Insert) - { - if (resp.StatusCode != HttpStatusCode.Created) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - } - else - { - if (resp.StatusCode != HttpStatusCode.NoContent) - { - throw StorageException.TranslateException(ex, cmd.CurrentResult); - } - } - } - - if (resp.Headers.ETag != null) - { - result.Etag = resp.Headers.ETag.ToString(); - if (operation.Entity != null) - { - operation.Entity.ETag = result.Etag; - } - } - - return result; - } - - internal static Task TableOperationPostProcess(TableResult result, TableOperation operation, RESTCommand cmd, HttpResponseMessage resp, OperationContext ctx) - { - return Task.Run(() => - { - if (operation.OperationType != TableOperationType.Retrieve && operation.OperationType != TableOperationType.Insert) - { - result.Etag = resp.Headers.ETag.ToString(); - operation.Entity.ETag = result.Etag; - } - else - { - // Parse entity - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - ReadOdataEntity(result, operation, new HttpResponseAdapterMessage(resp, cmd.ResponseStream), ctx, readerSettings); - } - - return result; - }); - } - - internal static Task> TableBatchOperationPostProcess(IList result, TableBatchOperation batch, RESTCommand> cmd, HttpResponseMessage resp, OperationContext ctx) - { - return Task.Run(() => - { - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, cmd.ResponseStream), readerSettings)) - { - // create a reader - ODataBatchReader reader = responseReader.CreateODataBatchReader(); - - // Initial => changesetstart - if (reader.State == ODataBatchReaderState.Initial) - { - reader.Read(); - } - - if (reader.State == ODataBatchReaderState.ChangesetStart) - { - // ChangeSetStart => Operation - reader.Read(); - } - - int index = 0; - bool failError = false; - bool failUnexpected = false; - - while (reader.State == ODataBatchReaderState.Operation) - { - TableOperation currentOperation = batch[index]; - TableResult currentResult = new TableResult() { Result = currentOperation.Entity }; - result.Add(currentResult); - - ODataBatchOperationResponseMessage mimePartResponseMessage = reader.CreateOperationResponseMessage(); - currentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - - // Validate Status Code - if (currentOperation.OperationType == TableOperationType.Insert) - { - failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.Conflict; - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.Created; - } - else if (currentOperation.OperationType == TableOperationType.Retrieve) - { - if (mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound) - { - index++; - - // Operation => next - reader.Read(); - continue; - } - - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.OK; - } - else - { - failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound; - failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; - } - - if (failError) - { - cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); - cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - throw new StorageException( - cmd.CurrentResult, - cmd.CurrentResult.ExtendedErrorInformation != null ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : SR.ExtendedErrorUnavailable, - null) - { - IsRetryable = false - }; - } - - if (failUnexpected) - { - cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); - cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; - - string indexString = Convert.ToString(index); - - // Attempt to extract index of failing entity from extended error info - if (cmd.CurrentResult.ExtendedErrorInformation != null && - !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) - { - string tempIndex = TableRequest.ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); - if (!string.IsNullOrEmpty(tempIndex)) - { - indexString = tempIndex; - } - } - - throw new StorageException(cmd.CurrentResult, SR.UnexpectedResponseCodeForOperation + indexString, null) { IsRetryable = true }; - } - - // Update etag - if (!string.IsNullOrEmpty(mimePartResponseMessage.GetHeader("ETag"))) - { - currentResult.Etag = mimePartResponseMessage.GetHeader("ETag"); - - if (currentOperation.Entity != null) - { - currentOperation.Entity.ETag = currentResult.Etag; - } - } - - // Parse Entity if needed - if (currentOperation.OperationType == TableOperationType.Retrieve || currentOperation.OperationType == TableOperationType.Insert) - { - ReadOdataEntity(currentResult, currentOperation, mimePartResponseMessage, ctx, readerSettings); - } - - index++; - - // Operation => - reader.Read(); - } - } - - return result; - }); - } - - internal static Task TableQueryPostProcess(Stream responseStream, HttpResponseMessage resp, OperationContext ctx) - { - return Task.Run(() => - { - TableQuerySegment retSeg = new TableQuerySegment(); - retSeg.ContinuationToken = ContinuationFromResponse(resp); - - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, responseStream), readerSettings)) - { - // create a reader - ODataReader reader = responseReader.CreateODataFeedReader(); - - // Start => FeedStart - if (reader.State == ODataReaderState.Start) - { - reader.Read(); - } - - // Feedstart - if (reader.State == ODataReaderState.FeedStart) - { - reader.Read(); - } - - while (reader.State == ODataReaderState.EntryStart) - { - // EntryStart => EntryEnd - reader.Read(); - - ODataEntry entry = (ODataEntry)reader.Item; - - DynamicTableEntity retEntity = new DynamicTableEntity(); - ReadAndUpdateTableEntity(retEntity, entry, EntityReadFlags.All, ctx); - retSeg.Results.Add(retEntity); - - // Entry End => ? - reader.Read(); - } - - DrainODataReader(reader); - } - - return retSeg; - }); - } - - internal static Task> TableQueryPostProcessGeneric(Stream responseStream, Func, string, TElement> resolver, HttpResponseMessage resp, OperationContext ctx) - { - return Task.Run(() => - { - ResultSegment retSeg = new ResultSegment(new List()); - retSeg.ContinuationToken = ContinuationFromResponse(resp); - - ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); - readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; - - using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, responseStream), readerSettings)) - { - // create a reader - ODataReader reader = responseReader.CreateODataFeedReader(); - - // Start => FeedStart - if (reader.State == ODataReaderState.Start) - { - reader.Read(); - } - - // Feedstart - if (reader.State == ODataReaderState.FeedStart) - { - reader.Read(); - } - - while (reader.State == ODataReaderState.EntryStart) - { - // EntryStart => EntryEnd - reader.Read(); - - ODataEntry entry = (ODataEntry)reader.Item; - - retSeg.Results.Add(ReadAndResolve(entry, resolver)); - - // Entry End => ? - reader.Read(); - } - - DrainODataReader(reader); - } - - return retSeg; - }); - } - - private static void DrainODataReader(ODataReader reader) - { - if (reader.State == ODataReaderState.FeedEnd) - { - reader.Read(); - } - - if (reader.State != ODataReaderState.Completed) - { - throw new InvalidOperationException(string.Format(SR.ODataReaderNotInCompletedState, reader.State)); - } - } - - /// - /// Gets the table continuation from response. - /// - /// The response. - /// The continuation. - internal static TableContinuationToken ContinuationFromResponse(HttpResponseMessage response) - { - IEnumerable nextPartitionKey; - IEnumerable nextRowKey; - IEnumerable nextTableName; - - response.Headers.TryGetValues( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextPartitionKey, - out nextPartitionKey); - response.Headers.TryGetValues( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextRowKey, - out nextRowKey); - response.Headers.TryGetValues( - TableConstants.TableServicePrefixForTableContinuation + TableConstants.TableServiceNextTableName, - out nextTableName); - - if (nextPartitionKey == null && nextRowKey == null && nextTableName == null) - { - return null; - } - - TableContinuationToken newContinuationToken = new TableContinuationToken() - { - NextPartitionKey = nextPartitionKey != null ? nextPartitionKey.FirstOrDefault() : null, - NextRowKey = nextRowKey != null ? nextRowKey.FirstOrDefault() : null, - NextTableName = nextTableName != null ? nextTableName.FirstOrDefault() : null - }; - - return newContinuationToken; - } - - private static void ReadOdataEntity(TableResult result, TableOperation operation, IODataResponseMessage respMsg, OperationContext ctx, ODataMessageReaderSettings readerSettings) - { - using (ODataMessageReader messageReader = new ODataMessageReader(respMsg, readerSettings)) - { - // create a reader - ODataReader reader = messageReader.CreateODataEntryReader(); - - while (reader.Read()) - { - if (reader.State == ODataReaderState.EntryEnd) - { - ODataEntry entry = (ODataEntry)reader.Item; - - if (operation.OperationType == TableOperationType.Retrieve) - { - result.Result = ReadAndResolve(entry, operation.RetrieveResolver); - result.Etag = entry.ETag; - } - else - { - result.Etag = ReadAndUpdateTableEntity( - operation.Entity, - entry, - EntityReadFlags.Timestamp | EntityReadFlags.Etag, - ctx); - } - } - } - - DrainODataReader(reader); - } - } - - private static T ReadAndResolve(ODataEntry entry, Func, string, T> resolver) - { - string pk = null; - string rk = null; - DateTimeOffset ts = new DateTimeOffset(); - Dictionary properties = new Dictionary(); - - foreach (ODataProperty prop in entry.Properties) - { - if (prop.Name == TableConstants.PartitionKey) - { - pk = (string)prop.Value; - } - else if (prop.Name == TableConstants.RowKey) - { - rk = (string)prop.Value; - } - else if (prop.Name == TableConstants.Timestamp) - { - ts = new DateTimeOffset((DateTime)prop.Value); - } - else - { - properties.Add(prop.Name, EntityProperty.CreateEntityPropertyFromObject(prop.Value)); - } - } - - return resolver(pk, rk, ts, properties, entry.ETag); - } - - // returns etag - internal static string ReadAndUpdateTableEntity(ITableEntity entity, ODataEntry entry, EntityReadFlags flags, OperationContext ctx) - { - if ((flags & EntityReadFlags.Etag) > 0) - { - entity.ETag = entry.ETag; - } - - Dictionary entityProperties = (flags & EntityReadFlags.Properties) > 0 ? new Dictionary() : null; - - if (flags > 0) - { - foreach (ODataProperty prop in entry.Properties) - { - if (prop.Name == TableConstants.PartitionKey) - { - if ((flags & EntityReadFlags.PartitionKey) == 0) - { - continue; - } - - entity.PartitionKey = (string)prop.Value; - } - else if (prop.Name == TableConstants.RowKey) - { - if ((flags & EntityReadFlags.RowKey) == 0) - { - continue; - } - - entity.RowKey = (string)prop.Value; - } - else if (prop.Name == TableConstants.Timestamp) - { - if ((flags & EntityReadFlags.Timestamp) == 0) - { - continue; - } - - entity.Timestamp = (DateTime)prop.Value; - } - else if ((flags & EntityReadFlags.Properties) > 0) - { - entityProperties.Add(prop.Name, EntityProperty.CreateEntityPropertyFromObject(prop.Value)); - } - } - - if ((flags & EntityReadFlags.Properties) > 0) - { - entity.ReadEntity(entityProperties, ctx); - } - } - - return entry.ETag; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableBatchOperation.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableBatchOperation.cs deleted file mode 100644 index 8a561d71af56e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableBatchOperation.cs +++ /dev/null @@ -1,74 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - using System.Net; - using System.Runtime.InteropServices.WindowsRuntime; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Windows.Foundation; - - /// - /// Represents a batch operation on a table. - /// - public sealed partial class TableBatchOperation : IList - { - internal IAsyncOperation> ExecuteAsync(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - if (this.operations.Count == 0) - { - throw new InvalidOperationException(SR.EmptyBatchOperation); - } - - RESTCommand> cmdToExecute = BatchImpl(this, client, tableName, modifiedOptions); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private static RESTCommand> BatchImpl(TableBatchOperation batch, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand> batchCmd = new RESTCommand>(client.Credentials, client.BaseUri); - batchCmd.ApplyRequestOptions(requestOptions); - - List results = new List(); - - batchCmd.RetrieveResponseStream = true; - batchCmd.Handler = client.AuthenticationHandler; - batchCmd.BuildClient = HttpClientFactory.BuildHttpClient; - batchCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableBatchOperation(cmd, cmd.ServerTimeoutInSeconds, client.BaseUri, tableName, batch, client, ctx); - batchCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp.StatusCode, results, cmd, ex); - batchCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableBatchOperationPostProcess(results, batch, cmd, resp, ctx); - batchCmd.RecoveryAction = (cmd, ex, ctx) => results.Clear(); - - return batchCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableOperation.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableOperation.cs deleted file mode 100644 index 7d9e3a29a5288..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableOperation.cs +++ /dev/null @@ -1,211 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - using System.Net; - using System.Net.Http; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Windows.Foundation; - - /// - /// Represents a single table operation. - /// - public sealed partial class TableOperation - { - internal IAsyncOperation ExecuteAsync(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - RESTCommand cmdToExecute = null; - - if (this.OperationType == TableOperationType.Insert || - this.OperationType == TableOperationType.InsertOrMerge || - this.OperationType == TableOperationType.InsertOrReplace) - { - if (!this.isTableEntity && this.OperationType != TableOperationType.Insert) - { - CommonUtility.AssertNotNull("Upserts require a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Upserts require a valid RowKey", this.Entity.RowKey); - } - - cmdToExecute = InsertImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Delete) - { - if (!this.isTableEntity) - { - CommonUtility.AssertNotNullOrEmpty("Delete requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Delete requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Delete requires a valid RowKey", this.Entity.RowKey); - } - - cmdToExecute = DeleteImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Merge) - { - CommonUtility.AssertNotNullOrEmpty("Merge requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Merge requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Merge requires a valid RowKey", this.Entity.RowKey); - - cmdToExecute = MergeImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Replace) - { - CommonUtility.AssertNotNullOrEmpty("Replace requires a valid ETag", this.Entity.ETag); - CommonUtility.AssertNotNull("Replace requires a valid PartitionKey", this.Entity.PartitionKey); - CommonUtility.AssertNotNull("Replace requires a valid RowKey", this.Entity.RowKey); - - cmdToExecute = ReplaceImpl(this, client, tableName, modifiedOptions); - } - else if (this.OperationType == TableOperationType.Retrieve) - { - cmdToExecute = RetrieveImpl(this, client, tableName, modifiedOptions); - } - else - { - throw new NotSupportedException(); - } - - return AsyncInfo.Run((cancellationToken) => Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private static RESTCommand InsertImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand insertCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - insertCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - insertCmd.RetrieveResponseStream = true; - insertCmd.Handler = client.AuthenticationHandler; - insertCmd.BuildClient = HttpClientFactory.BuildHttpClient; - insertCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx); - insertCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); - - insertCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx); - - return insertCmd; - } - - private static RESTCommand DeleteImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand deleteCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - deleteCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - deleteCmd.RetrieveResponseStream = false; - deleteCmd.Handler = client.AuthenticationHandler; - deleteCmd.BuildClient = HttpClientFactory.BuildHttpClient; - deleteCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx); - deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); - - return deleteCmd; - } - - private static RESTCommand MergeImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand mergeCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - mergeCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - mergeCmd.RetrieveResponseStream = false; - mergeCmd.Handler = client.AuthenticationHandler; - mergeCmd.BuildClient = HttpClientFactory.BuildHttpClient; - mergeCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx); - mergeCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); - - return mergeCmd; - } - - private static RESTCommand ReplaceImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand replaceCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - replaceCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult() { Result = operation.Entity }; - replaceCmd.RetrieveResponseStream = false; - replaceCmd.Handler = client.AuthenticationHandler; - replaceCmd.BuildClient = HttpClientFactory.BuildHttpClient; - replaceCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx); - replaceCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); - - return replaceCmd; - } - - private static RESTCommand RetrieveImpl(TableOperation operation, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - RESTCommand retrieveCmd = new RESTCommand(client.Credentials, operation.GenerateRequestURI(client.BaseUri, tableName)); - retrieveCmd.ApplyRequestOptions(requestOptions); - - TableResult result = new TableResult(); - retrieveCmd.RetrieveResponseStream = true; - retrieveCmd.Handler = client.AuthenticationHandler; - retrieveCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retrieveCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, cmd.ServerTimeoutInSeconds, operation, client, ctx); - retrieveCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); - retrieveCmd.PostProcessResponse = (cmd, resp, ctx) => - Task.Run(async () => - { - if (resp.StatusCode == HttpStatusCode.NotFound) - { - return result; - } - - result = await TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx); - return result; - }); - return retrieveCmd; - } - - internal HttpMethod HttpMethod - { - get - { - switch (this.OperationType) - { - case TableOperationType.Insert: - return HttpMethod.Post; - case TableOperationType.Merge: - case TableOperationType.InsertOrMerge: - return HttpMethod.Post; // Post tunneling for merge - case TableOperationType.Replace: - case TableOperationType.InsertOrReplace: - return HttpMethod.Put; - case TableOperationType.Delete: - return HttpMethod.Delete; - case TableOperationType.Retrieve: - return HttpMethod.Get; - default: - throw new NotSupportedException(); - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuery.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuery.cs deleted file mode 100644 index 035eb5ab5bfdf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuery.cs +++ /dev/null @@ -1,102 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - using System.Collections.Generic; - using System.Net; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Text; - using System.Threading.Tasks; - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using Windows.Foundation; - - /// - /// Represents a query against a specified table. - /// - public sealed partial class TableQuery - { - #region Impl - internal IEnumerable Execute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = - CommonUtility.LazyEnumerable( - (continuationToken) => - { - Task task = Task.Run(() => this.ExecuteQuerySegmentedAsync((TableContinuationToken)continuationToken, client, tableName, modifiedOptions, operationContext).AsTask()); - task.Wait(); - - TableQuerySegment seg = task.Result; - - return new ResultSegment((List)seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - - internal IAsyncOperation ExecuteQuerySegmentedAsync(TableContinuationToken continuationToken, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand cmdToExecute = QueryImpl(this, continuationToken, client, tableName, modifiedOptions); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private static RESTCommand QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions) - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand queryCmd = new RESTCommand(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.Handler = client.AuthenticationHandler; - queryCmd.BuildClient = HttpClientFactory.BuildHttpClient; - queryCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableQueryPostProcess(cmd.ResponseStream, resp, ctx); - - return queryCmd; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuerySegmentNonGeneric.cs b/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuerySegmentNonGeneric.cs deleted file mode 100644 index 55ab4c27152c2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/Table/TableQuerySegmentNonGeneric.cs +++ /dev/null @@ -1,77 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System.Collections.Generic; - - /// - /// Represents a table query segment. - /// - public sealed class TableQuerySegment : IEnumerable - { - internal TableQuerySegment() - { - this.Results = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The result. - internal TableQuerySegment(List result) - { - this.Results = result; - } - - internal TableQuerySegment(ResultSegment resSeg) - : this(resSeg.Results) - { - this.ContinuationToken = resSeg.ContinuationToken as TableContinuationToken; - } - - /// - /// Gets an enumerable collection of results. - /// - /// An enumerable collection of results. - public IList Results { get; internal set; } - - /// - /// Gets a continuation token to use to retrieve the next set of results with a subsequent call to the operation. - /// - /// The continuation token. - public TableContinuationToken ContinuationToken { get; internal set; } - - /// - /// Returns an enumerator that iterates through the collection. - /// - /// An enumerator that iterates through the collection. - public IEnumerator GetEnumerator() - { - return this.Results.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through a collection. - /// - /// An enumerator that iterates through a collection. - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return this.Results.GetEnumerator(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RT/WrappedStorageException.cs b/microsoft-azure-api/Services/Storage/Lib/RT/WrappedStorageException.cs deleted file mode 100644 index f40a03fd6ab25..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RT/WrappedStorageException.cs +++ /dev/null @@ -1,53 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Runtime.InteropServices; - using Microsoft.WindowsAzure.Storage.Core.Util; - - internal class WrappedStorageException : COMException - { - public WrappedStorageException(string msg, Exception inner, int hres) : base(msg, inner) - { - this.HResult = hres; - } - - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed.")] - internal static int GenerateHResult(Exception ex, RequestResult reqResult) - { - int hResult = WindowsAzureErrorCode.UnknownException; - - if (ex is StorageException) - { - int statusCode = (int)reqResult.HttpStatusCode; - if (statusCode >= 400 && statusCode < 600) - { - hResult = WindowsAzureErrorCode.HttpErrorMask | statusCode; - } - else if (ex.InnerException != null) - { - hResult = ex.InnerException.HResult; - } - } - - return hResult; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/CloudTableExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/CloudTableExtensions.cs deleted file mode 100644 index 4d081000bc22b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/CloudTableExtensions.cs +++ /dev/null @@ -1,125 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using Windows.Foundation; - - /// - /// Defines the extension methods to the class. This is a static class. - /// - public static class CloudTableExtensions - { - #region TableQuery Execute Methods - /// - /// Executes a query asynchronously in segmented mode with the specified query and continuation token. - /// - /// The entity type of the query. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object containing the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, TableContinuationToken token) where T : ITableEntity, new() - { - return table.ExecuteQuerySegmentedAsync(query, token, null /* requestOptions */, null /* operationContext */); - } - - /// - /// Executes a query asynchronously in segmented mode with the specified query, continuation token, options, and context. - /// - /// The entity type of the query. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A object containing the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) where T : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - return query.ExecuteQuerySegmentedAsync(token, table.ServiceClient, table.Name, requestOptions, operationContext); - } - - /// - /// Executes a query asynchronously in segmented mode, using the specified query and continuation token, and applies the to the result. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A containing the projection into type TResult of the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, EntityResolver resolver, TableContinuationToken token) where T : ITableEntity, new() - { - return table.ExecuteQuerySegmentedAsync(query, resolver, token, null /* requestOptions */, null /* operationContext */); - } - - /// - /// Executes a query asynchronously in segmented mode, using the specified query, continuation token, options, and context, and applies the to the result. - /// - /// The entity type of the query. - /// The type into which the will project the query results. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A containing the projection into type TResult of the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) where T : ITableEntity, new() - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - return query.ExecuteQuerySegmentedAsync(token, table.ServiceClient, table.Name, resolver, requestOptions, operationContext); - } - - /// - /// Executes a query asynchronously in segmented mode, using the specified continuation token, and applies the to the result. - /// - /// The type into which the will project the query results. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A containing the projection into type TResult of the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, EntityResolver resolver, TableContinuationToken token) - { - return table.ExecuteQuerySegmentedAsync(query, resolver, token, null /* requestOptions */, null /* operationContext */); - } - - /// - /// Executes a query asynchronously in segmented mode, using the specified continuation token, options, and context, and applies the to the result. - /// - /// The type into which the will project the query results. - /// The input , which acts as the this instance for the extension method. - /// A representing the query to execute. - /// An instance which creates a projection of the table query result entities into the specified type TResult. - /// A object representing a continuation token from the server when the operation returns a partial result. - /// A object that specifies execution options, such as retry policy and timeout settings, for the operation. - /// An object for tracking the current operation. - /// A containing the projection into type TResult of the results of executing the query. - public static IAsyncOperation> ExecuteQuerySegmentedAsync(this CloudTable table, TableQuery query, EntityResolver resolver, TableContinuationToken token, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNull("query", query); - CommonUtility.AssertNotNull("resolver", resolver); - return TableQueryExtensions.ExecuteQuerySegmentedAsync(query, token, table.ServiceClient, table.Name, resolver, requestOptions, operationContext); - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/IgnorePropertyAttribute.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/IgnorePropertyAttribute.cs deleted file mode 100644 index e8dfb657dc639..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/IgnorePropertyAttribute.cs +++ /dev/null @@ -1,26 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using System; - - [AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple = false)] - public sealed class IgnorePropertyAttribute : Attribute - { - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Lib/RTTable/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/RTTable/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/Properties/AssemblyInfo.cs deleted file mode 100644 index 25d8fc076a5ca..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.Storage.Tables.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] -[assembly: ComVisible(false)] - -#if SIGN -[assembly: InternalsVisibleTo( - "Microsoft.WindowsAzure.StorageRT.Test, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67" + - "871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0b" + - "d333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307" + - "e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c3" + - "08055da9")] -#else -[assembly: InternalsVisibleTo("Microsoft.WindowsAzure.StorageRT.Test")] -#endif -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/RTTable.csproj b/microsoft-azure-api/Services/Storage/Lib/RTTable/RTTable.csproj deleted file mode 100644 index d3cad77c57a74..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/RTTable.csproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {91930F51-683B-4933-A452-7D8DDFDBB1AC} - Library - Properties - Microsoft.WindowsAzure.Storage.Table - Microsoft.WindowsAzure.Storage.Table - en-US - 512 - {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NETFX_CORE;WINDOWS_RT - prompt - 4 - - - true - MSSharedLibKey.snk - true - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_RT;SIGN - prompt - 4 - - - - - {42cb7861-70bb-4f34-a815-4355e6ea2589} - RT %28Lib\RT%29 - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/Settings.StyleCop b/microsoft-azure-api/Services/Storage/Lib/RTTable/Settings.StyleCop deleted file mode 100644 index 6db23a76d6dd4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/Settings.StyleCop +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableBatchOperationExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/TableBatchOperationExtensions.cs deleted file mode 100644 index 1f5401ff6bdfa..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableBatchOperationExtensions.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - - /// - /// Defines the extension methods to the class. This is a static class. - /// - public static class TableBatchOperationExtensions - { - /// - /// Adds a table operation that retrieves an entity with the specified partition key and row key to the batch operation. The entity will be deserialized into the specified class type which extends . - /// - /// The class of type for the entity to retrieve. - /// The input , which acts as the this instance for the extension method. - /// A string containing the partition key of the entity to be retrieved. - /// A string containing the row key of the entity to be retrieved. - public static void Retrieve(this TableBatchOperation batch, string partitionKey, string rowkey) where TElement : ITableEntity - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Add the table operation. - batch.Add(new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey, RetrieveResolver = (pk, rk, ts, prop, etag) => EntityUtilities.ResolveEntityByType(pk, rk, ts, prop, etag) }); - } - - /// - /// Adds a table operation that retrieves an entity with the specified partition key and row key to the batch operation. - /// - /// The return type which the specified will resolve the given entity to. - /// The input , which acts as the this instance for the extension method. - /// A string containing the partition key of the entity to be retrieved. - /// A string containing the row key of the entity to be retrieved. - /// The implementation to project the entity to retrieve as a particular type in the result. - public static void Retrieve(this TableBatchOperation batch, string partitionKey, string rowkey, EntityResolver resolver) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Add the table operation. - batch.Add(new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey, RetrieveResolver = (pk, rk, ts, prop, etag) => resolver(pk, rk, ts, prop, etag) }); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableOperationFactory.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/TableOperationFactory.cs deleted file mode 100644 index c2a61088f5d0d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableOperationFactory.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - - /// - /// Contains factory methods for creating objects. - /// - public static class TableOperationFactory - { - /// - /// Creates a new object that retrieves an entity with the specified partition key and row key. The entity will be deserialized into the specified class type which extends . - /// - /// A string containing the partition key of the entity to be retrieved. - /// A string containing the row key of the entity to be retrieved. - /// The class of type for the entity to retrieve. - /// A new object. - public static TableOperation Retrieve(string partitionKey, string rowkey) where TElement : ITableEntity - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Create and return the table operation. - return new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey, RetrieveResolver = (pk, rk, ts, prop, etag) => EntityUtilities.ResolveEntityByType(pk, rk, ts, prop, etag) }; - } - - /// - /// Creates a new object that retrieves an entity with the specified partition key and row key. - /// - /// A string containing the partition key of the entity to be retrieved. - /// A string containing the row key of the entity to be retrieved. - /// The implementation to project the entity to retrieve as a particular type in the result. - /// The return type which the specified will resolve the given entity to. - /// A new object. - public static TableOperation Retrieve(string partitionKey, string rowkey, EntityResolver resolver) - { - CommonUtility.AssertNotNull("partitionKey", partitionKey); - CommonUtility.AssertNotNull("rowkey", rowkey); - - // Create and return the table operation. - return new TableOperation(null /* entity */, TableOperationType.Retrieve) { RetrievePartitionKey = partitionKey, RetrieveRowKey = rowkey, RetrieveResolver = (pk, rk, ts, prop, etag) => resolver(pk, rk, ts, prop, etag) }; - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQuery.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQuery.cs deleted file mode 100644 index eb56520aafcbb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQuery.cs +++ /dev/null @@ -1,156 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Collections.Generic; - using System.Net; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - using Windows.Foundation; - - /// - /// Represents a query against a specified table. - /// - /// The entity type of the query. - public partial class TableQuery where TElement : ITableEntity, new() - { - /// - /// Initializes a new instance of the class. - /// - public TableQuery() - { - } - - #region Impl - - internal IEnumerable Execute(CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = - CommonUtility.LazyEnumerable( - (continuationToken) => - { - Task> task = Task.Run(() => this.ExecuteQuerySegmentedAsync((TableContinuationToken)continuationToken, client, tableName, modifiedOptions, operationContext).AsTask()); - task.Wait(); - - TableQuerySegment seg = task.Result; - - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - - internal IAsyncOperation> ExecuteQuerySegmentedAsync(TableContinuationToken token, CloudTableClient client, string tableName, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, EntityUtilities.ResolveEntityByType, modifiedOptions); - - return AsyncInfo.Run(async (continuationToken) => await Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - continuationToken)); - } - - internal IEnumerable Execute(CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - IEnumerable enumerable = - CommonUtility.LazyEnumerable( - (continuationToken) => - { - Task> task = Task.Run(() => this.ExecuteQuerySegmentedAsync((TableContinuationToken)continuationToken, client, tableName, resolver, modifiedOptions, operationContext).AsTask()); - task.Wait(); - - TableQuerySegment seg = task.Result; - - return new ResultSegment(seg.Results) { ContinuationToken = seg.ContinuationToken }; - }, - this.takeCount.HasValue ? this.takeCount.Value : long.MaxValue); - - return enumerable; - } - - internal IAsyncOperation> ExecuteQuerySegmentedAsync(TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - CommonUtility.AssertNotNull("resolver", resolver); - - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(this, token, client, tableName, resolver, modifiedOptions); - - return AsyncInfo.Run((cancellationToken) => Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private static RESTCommand> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions) where T : ITableEntity, new() - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand> queryCmd = new RESTCommand>(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.Handler = client.AuthenticationHandler; - queryCmd.BuildClient = HttpClientFactory.BuildHttpClient; - queryCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = async (cmd, resp, ctx) => - { - ResultSegment resSeg = await TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(cmd.ResponseStream, resolver.Invoke, resp, ctx); - return new TableQuerySegment(resSeg); - }; - - return queryCmd; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQueryExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQueryExtensions.cs deleted file mode 100644 index 80dcfd2cc745c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/TableQueryExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Table -{ - using Microsoft.WindowsAzure.Storage.Core; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - using Microsoft.WindowsAzure.Storage.Shared.Protocol; - using Microsoft.WindowsAzure.Storage.Table.Protocol; - using System; - using System.Net; - using System.Runtime.InteropServices.WindowsRuntime; - using Windows.Foundation; - - /// - /// Defines the extension methods to the class. This is a static class. - /// - internal static class TableQueryExtensions - { - internal static IAsyncOperation> ExecuteQuerySegmentedAsync(TableQuery query, TableContinuationToken continuationToken, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions, OperationContext operationContext) - { - CommonUtility.AssertNotNullOrEmpty("tableName", tableName); - TableRequestOptions modifiedOptions = TableRequestOptions.ApplyDefaults(requestOptions, client); - operationContext = operationContext ?? new OperationContext(); - - RESTCommand> cmdToExecute = QueryImpl(query, continuationToken, client, tableName, resolver, modifiedOptions); - - return AsyncInfo.Run(async (cancellationToken) => await Executor.ExecuteAsync( - cmdToExecute, - modifiedOptions.RetryPolicy, - operationContext, - cancellationToken)); - } - - private static RESTCommand> QueryImpl(TableQuery query, TableContinuationToken token, CloudTableClient client, string tableName, EntityResolver resolver, TableRequestOptions requestOptions) - { - Uri tempUri = NavigationHelper.AppendPathToUri(client.BaseUri, tableName); - UriQueryBuilder builder = query.GenerateQueryBuilder(); - - if (token != null) - { - token.ApplyToUriQueryBuilder(builder); - } - - Uri reqUri = builder.AddToUri(tempUri); - - RESTCommand> queryCmd = new RESTCommand>(client.Credentials, reqUri); - queryCmd.ApplyRequestOptions(requestOptions); - - queryCmd.RetrieveResponseStream = true; - queryCmd.Handler = client.AuthenticationHandler; - queryCmd.BuildClient = HttpClientFactory.BuildHttpClient; - queryCmd.BuildRequest = (cmd, cnt, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(cmd.Uri, cmd.ServerTimeoutInSeconds, ctx); - queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); - queryCmd.PostProcessResponse = async (cmd, resp, ctx) => - { - ResultSegment resSeg = await TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(cmd.ResponseStream, resolver.Invoke, resp, ctx); - return new TableQuerySegment(resSeg); - }; - - return queryCmd; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/RTTable/WindowsAzure.Storage.Table-Preview.nuspec b/microsoft-azure-api/Services/Storage/Lib/RTTable/WindowsAzure.Storage.Table-Preview.nuspec deleted file mode 100644 index 9c7f52cac6ca0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/RTTable/WindowsAzure.Storage.Table-Preview.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - WindowsAzure.Storage.Table-Preview - 2.1.0.4-preview - Windows Azure Storage Tables Extension for Windows Runtime - Microsoft - Microsoft - http://go.microsoft.com/fwlink/?LinkId=235170 - http://go.microsoft.com/fwlink/?LinkId=235168 - http://go.microsoft.com/fwlink/?LinkID=288890 - true - This table extension library provides support for strong entity types (POCOs), generic queries, reflection based serialization and the EntityResolver for languages other than JavaScript when developing Windows Store Apps. -Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ - A table extension library for Windows Runtime for working with Windows Azure Storage tables. - Microsoft, Azure, Storage, Table, Scalable, winrt, windowsazureofficial - - - - - - - - - - - - - - diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.Edm.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.Edm.Portable.dll deleted file mode 100644 index 545d84e308174..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.Edm.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.OData.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.OData.Portable.dll deleted file mode 100644 index 56a64aa61112e..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/Microsoft.Data.OData.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/System.Spatial.Portable.dll b/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/System.Spatial.Portable.dll deleted file mode 100644 index a7d191c73050b..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/WP/Dependencies/System.Spatial.Portable.dll and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Lib/WP/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Lib/WP/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Lib/WP/Properties/AssemblyInfo.cs deleted file mode 100644 index 6e46da11eb1db..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Resources; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.Storage.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("cf1d432a-380f-434a-bc43-fc39ac8b61a8")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] -[assembly: NeutralResourcesLanguageAttribute("en-US")] - -#if SIGN -[assembly: InternalsVisibleTo( - "Microsoft.WindowsAzure.Storage.Test, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67" + - "871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0b" + - "d333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307" + - "e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c3" + - "08055da9")] -#else -[assembly: InternalsVisibleTo("Microsoft.WindowsAzure.Storage.Test")] -#endif \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Settings.StyleCop b/microsoft-azure-api/Services/Storage/Lib/WP/Settings.StyleCop deleted file mode 100644 index a693cb5df9439..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/Settings.StyleCop +++ /dev/null @@ -1,318 +0,0 @@ - - - - abc - api - Bool - canonicalizing - creds - dequeue - dequeued - Edm - EdmType - Enum - etag - ETag - Fisma - func - impl - Md - myblob - mycontainer - myfolder - parsable - Postcondition - Retryable - sas - testaccount - testcontainer - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/HttpResponseHeader.cs b/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/HttpResponseHeader.cs deleted file mode 100644 index c2cebfa121f55..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/HttpResponseHeader.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - internal static class HttpResponseHeader - { - // Summary: - // The Cache-Control header, which specifies caching directives that must be - // obeyed by all caching mechanisms along the request/response chain. - public const string CacheControl = "Cache-Control"; - - // Summary: - // The Content-Type header, which specifies the MIME type of the accompanying - // body data. - public const string ContentType = "Content-Type"; - - // Summary: - // The Etag header, which specifies the current value for the requested variant. - public const string ETag = "Etag"; - - // Summary: - // The Last-Modified header, which specifies the date and time the requested - // variant was last modified. - public const string LastModified = "Last-Modified"; - - // Summary: - // The Content-MD5 header, which specifies the MD5 digest of the accompanying - // body data, for the purpose of providing an end-to-end message integrity check. - public const string ContentMd5 = "Content-MD5"; - - // Summary: - // The Range header, which specifies the subrange or subranges of the response - // that the client requests be returned in lieu of the entire response. - public const string ContentRange = "Range"; - - // Summary: - // The Content-Encoding header, which specifies the encodings that have been - // applied to the accompanying body data. - public const string ContentEncoding = "Content-Encoding"; - - // Summary: - // The Content-Langauge header, which specifies the natural language or languages - // of the accompanying body data. - public const string ContentLanguage = "Content-Langauge"; - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebHeaderCollectionExtensions.cs b/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebHeaderCollectionExtensions.cs deleted file mode 100644 index 7259760e68d26..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebHeaderCollectionExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - using System.Net; - - internal static class WebHeaderCollectionExtensions - { - internal static void Add(this WebHeaderCollection col, string name, string value) - { - string existingValue = col[name]; - - value = value ?? string.Empty; - - // We should not check for IsNullOrEmpty here, since empty header is a valid value - if (existingValue == null) - { - col[name] = value.Trim(); - } - else - { - col[name] = string.Concat(existingValue, ",", value.Trim()); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebRequestMethods.cs b/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebRequestMethods.cs deleted file mode 100644 index c2e9210369ed7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/Shared/Protocol/WebRequestMethods.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Shared.Protocol -{ - public static class WebRequestMethods - { - // Summary: - // Represents the types of HTTP protocol methods that can be used with an HTTP - // request. - public static class Http - { - // Summary: - // Represents the HTTP CONNECT protocol method that is used with a proxy that - // can dynamically switch to tunneling, as in the case of SSL tunneling. - public const string Connect = "CONNECT"; - - // Summary: - // Represents an HTTP GET protocol method. - public const string Get = "GET"; - - // Summary: - // Represents an HTTP HEAD protocol method. The HEAD method is identical to - // GET except that the server only returns message-headers in the response, - // without a message-body. - public const string Head = "HEAD"; - - // Summary: - // Represents an HTTP MKCOL request that creates a new collection (such as a - // collection of pages) at the location specified by the request-Uniform Resource - // Identifier (URI). - public const string MkCol = "MKCOL"; - - // Summary: - // Represents an HTTP POST protocol method that is used to post a new entity - // as an addition to a URI. - public const string Post = "POST"; - - // Summary: - // Represents an HTTP PUT protocol method that is used to replace an entity - // identified by a URI. - public const string Put = "PUT"; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Lib/WP/WP.csproj b/microsoft-azure-api/Services/Storage/Lib/WP/WP.csproj deleted file mode 100644 index 81cb0d7a34e48..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WP/WP.csproj +++ /dev/null @@ -1,217 +0,0 @@ - - - - Debug - AnyCPU - 10.0.20506 - 2.0 - {CF1D432A-380F-434A-BC43-FC39AC8B61A8} - {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.Storage - v8.0 - - - - - WindowsPhone - false - true - true - 11.0 - - - true - full - false - Bin\Debug - TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;WINDOWS_DESKTOP;APM;TASK - true - true - prompt - 4 - false - - - true - MSSharedLibKey.snk - true - pdbonly - true - Bin\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE;WINDOWS_DESKTOP;APM;TASK;SIGN - true - true - prompt - 4 - false - - - true - Bin\x86\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE;WINDOWS_DESKTOP;APM;TASK - true - full - - - prompt - false - - - Bin\x86\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE;WINDOWS_DESKTOP;APM;TASK - true - true - pdbonly - - - prompt - - - true - Bin\ARM\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE;DNCP;APM;TASK - true - full - - - prompt - false - - - Bin\ARM\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE;DNCP;APM;TASK - true - true - pdbonly - - - prompt - - - - Dependencies\Microsoft.Data.Edm.Portable.dll - - - Dependencies\Microsoft.Data.OData.Portable.dll - - - Dependencies\System.Spatial.Portable.dll - - - - - - - - - - - - Auth\Auth - - - Auth\Protocol\Protocol - - - Blob\Blob - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Queue\Protocol\Protocol - - - Table\Tables - - - Table\Protocol\Protocol - - - Shared\Protocol\Protocol - - - Core\Core - - - Core\Auth\Auth - - - Core\Util\Util - - - Core\Executor\Executor - - - - - - - - Auth\Auth - - - - Core\Core - - - Core\Auth\Auth - - - Core\Executor\Executor - - - Core\Util\Util - - - - RetryPolicies\RetryPolicies - - - Blob\Blob - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Queue\Protocol\Protocol - - - Table\Queryable\Queryable - - - Table\Table - - - Table\Protocol\Protocol - - - Shared\Shared - - - Shared\Protocol\Protocol - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Lib/WindowsAzure.Storage-Preview.nuspec b/microsoft-azure-api/Services/Storage/Lib/WindowsAzure.Storage-Preview.nuspec deleted file mode 100644 index bec1d80caa1af..0000000000000 --- a/microsoft-azure-api/Services/Storage/Lib/WindowsAzure.Storage-Preview.nuspec +++ /dev/null @@ -1,34 +0,0 @@ - - - - WindowsAzure.Storage-Preview - 2.1.0.4-preview - Windows Azure Storage - Microsoft - Microsoft - http://go.microsoft.com/fwlink/?LinkId=235170 - http://go.microsoft.com/fwlink/?LinkId=235168 - http://go.microsoft.com/fwlink/?LinkID=288890 - true - This client library enables working with the Windows Azure storage services which include the blob service for storing binary and text data, the table service for storing structured non-relational data, and the queue service for storing messages that may be accessed by a client. -For this release see notes - https://github.com/WindowsAzure/azure-sdk-for-net/blob/preview/microsoft-azure-api/Services/Storage/changelog.txt -Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ - A client library for Windows Phone and Windows Runtime for working with Windows Azure storage services including blobs, tables, and queues. - Microsoft, Azure, Storage, Table, Blob, Queue, Scalable, winrt, windowsphone, windowsazureofficial - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Microsoft.WindowsAzure.Storage.sln b/microsoft-azure-api/Services/Storage/Microsoft.WindowsAzure.Storage.sln deleted file mode 100644 index e8d2ae18b7396..0000000000000 --- a/microsoft-azure-api/Services/Storage/Microsoft.WindowsAzure.Storage.sln +++ /dev/null @@ -1,201 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{CE1EB2B6-0DA8-43D4-A2E1-001804697009}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet40", "Lib\DotNet40\DotNet40.csproj", "{C6787633-B26A-4913-A762-4C0FFCEB6FE3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RT", "Lib\RT\RT.csproj", "{42CB7861-70BB-4F34-A815-4355E6EA2589}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RTTable", "Lib\RTTable\RTTable.csproj", "{91930F51-683B-4933-A452-7D8DDFDBB1AC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{CD7D43DF-B62D-40B1-927C-AEE326941FEA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unit", "Unit", "{B4CE45FC-1ACB-4691-BC23-D94984B7D9F5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FaultInjection", "FaultInjection", "{437E79C3-9AD3-499D-92A4-75DCE81A8833}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpMangler", "Test\Unit\FaultInjection\HttpMangler\HttpMangler.csproj", "{CA607E8F-2906-4065-A1A9-4A3733F0CC31}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XStoreMangler", "Test\Unit\FaultInjection\XStoreMangler\XStoreMangler.csproj", "{6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet40", "Test\Unit\DotNet40\DotNet40.csproj", "{1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RT", "Test\Unit\RT\RT.csproj", "{B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WP", "Lib\WP\WP.csproj", "{CF1D432A-380F-434A-BC43-FC39AC8B61A8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WP", "Test\Unit\WP\WP.csproj", "{9456513A-1DDD-44E8-9FF0-985317F29A50}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|Mixed Platforms = Release|Mixed Platforms - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|ARM.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|x64.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Debug|x86.ActiveCfg = Debug|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Any CPU.Build.0 = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|ARM.ActiveCfg = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|x64.ActiveCfg = Release|Any CPU - {C6787633-B26A-4913-A762-4C0FFCEB6FE3}.Release|x86.ActiveCfg = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|ARM.ActiveCfg = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|x64.ActiveCfg = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Debug|x86.ActiveCfg = Debug|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|Any CPU.Build.0 = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|ARM.ActiveCfg = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|x64.ActiveCfg = Release|Any CPU - {42CB7861-70BB-4F34-A815-4355E6EA2589}.Release|x86.ActiveCfg = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|ARM.ActiveCfg = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|x64.ActiveCfg = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Debug|x86.ActiveCfg = Debug|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|Any CPU.Build.0 = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|ARM.ActiveCfg = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|x64.ActiveCfg = Release|Any CPU - {91930F51-683B-4933-A452-7D8DDFDBB1AC}.Release|x86.ActiveCfg = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|ARM.ActiveCfg = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|x64.ActiveCfg = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Debug|x86.ActiveCfg = Debug|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|Any CPU.Build.0 = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|ARM.ActiveCfg = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|x64.ActiveCfg = Release|Any CPU - {CA607E8F-2906-4065-A1A9-4A3733F0CC31}.Release|x86.ActiveCfg = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|x64.ActiveCfg = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Debug|x86.ActiveCfg = Debug|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|Any CPU.Build.0 = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|ARM.ActiveCfg = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|x64.ActiveCfg = Release|Any CPU - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B}.Release|x86.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|x64.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|x86.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Any CPU.Build.0 = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|ARM.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|x64.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|x86.ActiveCfg = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|x64.ActiveCfg = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Debug|x86.ActiveCfg = Debug|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Any CPU.Build.0 = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Any CPU.Deploy.0 = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|ARM.ActiveCfg = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|x64.ActiveCfg = Release|Any CPU - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7}.Release|x86.ActiveCfg = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|ARM.ActiveCfg = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|x64.ActiveCfg = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Debug|x86.ActiveCfg = Debug|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|Any CPU.Build.0 = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|ARM.ActiveCfg = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|x64.ActiveCfg = Release|Any CPU - {CF1D432A-380F-434A-BC43-FC39AC8B61A8}.Release|x86.ActiveCfg = Release|Any CPU - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Any CPU.ActiveCfg = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Any CPU.Build.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Any CPU.Deploy.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|ARM.ActiveCfg = Debug|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|ARM.Build.0 = Debug|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|ARM.Deploy.0 = Debug|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|Mixed Platforms.Deploy.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|x64.ActiveCfg = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|x86.ActiveCfg = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|x86.Build.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Debug|x86.Deploy.0 = Debug|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|Any CPU.ActiveCfg = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|ARM.ActiveCfg = Release|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|ARM.Build.0 = Release|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|ARM.Deploy.0 = Release|ARM - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|Mixed Platforms.Build.0 = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|Mixed Platforms.Deploy.0 = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|x64.ActiveCfg = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|x86.ActiveCfg = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|x86.Build.0 = Release|x86 - {9456513A-1DDD-44E8-9FF0-985317F29A50}.Release|x86.Deploy.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {C6787633-B26A-4913-A762-4C0FFCEB6FE3} = {CE1EB2B6-0DA8-43D4-A2E1-001804697009} - {42CB7861-70BB-4F34-A815-4355E6EA2589} = {CE1EB2B6-0DA8-43D4-A2E1-001804697009} - {91930F51-683B-4933-A452-7D8DDFDBB1AC} = {CE1EB2B6-0DA8-43D4-A2E1-001804697009} - {CF1D432A-380F-434A-BC43-FC39AC8B61A8} = {CE1EB2B6-0DA8-43D4-A2E1-001804697009} - {B4CE45FC-1ACB-4691-BC23-D94984B7D9F5} = {CD7D43DF-B62D-40B1-927C-AEE326941FEA} - {437E79C3-9AD3-499D-92A4-75DCE81A8833} = {B4CE45FC-1ACB-4691-BC23-D94984B7D9F5} - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B} = {B4CE45FC-1ACB-4691-BC23-D94984B7D9F5} - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7} = {B4CE45FC-1ACB-4691-BC23-D94984B7D9F5} - {9456513A-1DDD-44E8-9FF0-985317F29A50} = {B4CE45FC-1ACB-4691-BC23-D94984B7D9F5} - {CA607E8F-2906-4065-A1A9-4A3733F0CC31} = {437E79C3-9AD3-499D-92A4-75DCE81A8833} - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B} = {437E79C3-9AD3-499D-92A4-75DCE81A8833} - EndGlobalSection -EndGlobal diff --git a/microsoft-azure-api/Services/Storage/Test/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Test/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/BlobTestBase.Common.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/BlobTestBase.Common.cs deleted file mode 100644 index bebbc2e9f6742..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/BlobTestBase.Common.cs +++ /dev/null @@ -1,134 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.IO; - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - public partial class BlobTestBase : TestBase - { - public static string GetRandomContainerName() - { - return string.Concat("testc", Guid.NewGuid().ToString("N")); - } - - public static CloudBlobContainer GetRandomContainerReference() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - string name = GetRandomContainerName(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - return container; - } - - public static List GetBlockIdList(int count) - { - List blocks = new List(); - for (int i = 0; i < count; i++) - { - blocks.Add(Convert.ToBase64String(Guid.NewGuid().ToByteArray())); - } - return blocks; - } - - public static void SeekRandomly(Stream stream, long offset) - { - Random random = new Random(); - int randomOrigin = random.Next(3); - SeekOrigin origin = SeekOrigin.Begin; - switch (randomOrigin) - { - case 1: - origin = SeekOrigin.Current; - offset = offset - stream.Position; - break; - - case 2: - origin = SeekOrigin.End; - offset = offset - stream.Length; - break; - } - stream.Seek(offset, origin); - } - - public static void AssertAreEqual(ICloudBlob blob1, ICloudBlob blob2) - { - if (blob1 == null) - { - Assert.IsNull(blob2); - } - else - { - Assert.IsNotNull(blob2); - Assert.AreEqual(blob1.BlobType, blob2.BlobType); - Assert.AreEqual(blob1.Uri, blob2.Uri); - Assert.AreEqual(blob1.SnapshotTime, blob2.SnapshotTime); - Assert.AreEqual(blob1.IsSnapshot, blob2.IsSnapshot); - Assert.AreEqual(blob1.SnapshotQualifiedUri, blob2.SnapshotQualifiedUri); - AssertAreEqual(blob1.Properties, blob2.Properties); - AssertAreEqual(blob1.CopyState, blob2.CopyState); - } - } - - public static void AssertAreEqual(BlobProperties prop1, BlobProperties prop2) - { - if (prop1 == null) - { - Assert.IsNull(prop2); - } - else - { - Assert.IsNotNull(prop2); - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - Assert.AreEqual(prop1.ETag, prop2.ETag); - Assert.AreEqual(prop1.LastModified, prop2.LastModified); - Assert.AreEqual(prop1.Length, prop2.Length); - } - } - - public static void AssertAreEqual(CopyState copy1, CopyState copy2) - { - if (copy1 == null) - { - Assert.IsNull(copy2); - } - else - { - Assert.IsNotNull(copy2); - Assert.AreEqual(copy1.BytesCopied, copy2.BytesCopied); - Assert.AreEqual(copy1.CompletionTime, copy2.CompletionTime); - Assert.AreEqual(copy1.CopyId, copy2.CopyId); - Assert.AreEqual(copy1.Source, copy2.Source); - Assert.AreEqual(copy1.Status, copy2.Status); - Assert.AreEqual(copy1.TotalBytes, copy2.TotalBytes); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/NonSeekableMemoryStream.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/NonSeekableMemoryStream.cs deleted file mode 100644 index 53d8bec715d99..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Blob/NonSeekableMemoryStream.cs +++ /dev/null @@ -1,84 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -using System; -using System.IO; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - public class NonSeekableMemoryStream : MemoryStream - { - public NonSeekableMemoryStream() - : base() - { - } - - public NonSeekableMemoryStream(byte[] buffer) - : base(buffer) - { - } - - public override bool CanSeek - { - get - { - return false; - } - } - - public override long Length - { - get - { - throw new NotSupportedException(); - } - } - - public override long Position - { - get - { - throw new NotSupportedException(); - } - set - { - throw new NotSupportedException(); - } - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public void ForceSeek(long offset, SeekOrigin origin) - { - base.Seek(offset, origin); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/AlwaysRetry.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/AlwaysRetry.cs deleted file mode 100644 index 4b956e031be57..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/AlwaysRetry.cs +++ /dev/null @@ -1,45 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using System; - - public class AlwaysRetry : IRetryPolicy - { - private TimeSpan deltaBackoff; - private int maximumAttempts; - - public AlwaysRetry(TimeSpan deltaBackoff, int maxAttempts) - { - this.deltaBackoff = deltaBackoff; - this.maximumAttempts = maxAttempts; - } - - public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext) - { - retryInterval = this.deltaBackoff; - return currentRetryCount < this.maximumAttempts; - } - - public IRetryPolicy CreateInstance() - { - return new AlwaysRetry(this.deltaBackoff, this.maximumAttempts); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/CloudStorageAccountTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/CloudStorageAccountTests.cs deleted file mode 100644 index b92da5fd758df..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/CloudStorageAccountTests.cs +++ /dev/null @@ -1,765 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Globalization; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Blob; -using Microsoft.WindowsAzure.Storage.Queue; -using Microsoft.WindowsAzure.Storage.Table; - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - [TestClass] - public class CloudStorageAccountTests : TestBase - { - private string token = "?sp=abcde&sig=1"; - - [TestMethod] - /// [Description("Anonymous credentials")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsAnonymous() - { - StorageCredentials cred = new StorageCredentials(); - - Assert.IsNull(cred.AccountName); - Assert.IsTrue(cred.IsAnonymous); - Assert.IsFalse(cred.IsSAS); - Assert.IsFalse(cred.IsSharedKey); - - Uri testUri = new Uri("http://test/abc?querya=1"); - Assert.AreEqual(testUri, cred.TransformUri(testUri)); - - byte[] dummyKey = { 0, 1, 2 }; - string base64EncodedDummyKey = Convert.ToBase64String(dummyKey); - TestHelper.ExpectedException( - () => cred.UpdateKey(base64EncodedDummyKey), - "Updating shared key on an anonymous credentials instance should fail."); - - - } - - [TestMethod] - /// [Description("Shared key credentials")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsSharedKey() - { - StorageCredentials cred = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - - Assert.AreEqual(TestBase.TargetTenantConfig.AccountName, cred.AccountName, false); - Assert.IsFalse(cred.IsAnonymous); - Assert.IsFalse(cred.IsSAS); - Assert.IsTrue(cred.IsSharedKey); - - Uri testUri = new Uri("http://test/abc?querya=1"); - Assert.AreEqual(testUri, cred.TransformUri(testUri)); - - Assert.AreEqual(TestBase.TargetTenantConfig.AccountKey, cred.ExportBase64EncodedKey()); - byte[] dummyKey = { 0, 1, 2 }; - string base64EncodedDummyKey = Convert.ToBase64String(dummyKey); - cred.UpdateKey(base64EncodedDummyKey); - Assert.AreEqual(base64EncodedDummyKey, cred.ExportBase64EncodedKey()); - -#if !WINDOWS_RT - dummyKey[0] = 3; - base64EncodedDummyKey = Convert.ToBase64String(dummyKey); - cred.UpdateKey(dummyKey); - Assert.AreEqual(base64EncodedDummyKey, cred.ExportBase64EncodedKey()); -#endif - } - - [TestMethod] - /// [Description("SAS token credentials")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsSAS() - { - StorageCredentials cred = new StorageCredentials(token); - - Assert.IsNull(cred.AccountName); - Assert.IsFalse(cred.IsAnonymous); - Assert.IsTrue(cred.IsSAS); - Assert.IsFalse(cred.IsSharedKey); - - Uri testUri = new Uri("http://test/abc"); - Assert.AreEqual(testUri.AbsoluteUri + token, cred.TransformUri(testUri).AbsoluteUri, true); - - testUri = new Uri("http://test/abc?query=a&query2=b"); - string expectedUri = testUri.AbsoluteUri + "&" + token.Substring(1); - Assert.AreEqual(expectedUri, cred.TransformUri(testUri).AbsoluteUri, true); - - byte[] dummyKey = { 0, 1, 2 }; - string base64EncodedDummyKey = Convert.ToBase64String(dummyKey); - TestHelper.ExpectedException( - () => cred.UpdateKey(base64EncodedDummyKey), - "Updating shared key on a SAS credentials instance should fail."); - } - - [TestMethod] - /// [Description("CloudStorageAccount object with an empty key value.")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsEmptyKeyValue() - { - string accountName = TestBase.TargetTenantConfig.AccountName; - string keyValue = TestBase.TargetTenantConfig.AccountKey; - string emptyKeyValueAsString = string.Empty; - string emptyKeyConnectionString = string.Format(CultureInfo.InvariantCulture, "DefaultEndpointsProtocol=https;AccountName={0};AccountKey=", accountName); - - StorageCredentials credentials1 = new StorageCredentials(accountName, emptyKeyValueAsString); - Assert.AreEqual(accountName, credentials1.AccountName); - Assert.IsFalse(credentials1.IsAnonymous); - Assert.IsFalse(credentials1.IsSAS); - Assert.IsTrue(credentials1.IsSharedKey); - Assert.AreEqual(emptyKeyValueAsString, Convert.ToBase64String(credentials1.ExportKey())); - - CloudStorageAccount account1 = new CloudStorageAccount(credentials1, true); - Assert.AreEqual(emptyKeyConnectionString, account1.ToString(true)); - Assert.IsNotNull(account1.Credentials); - Assert.AreEqual(accountName, account1.Credentials.AccountName); - Assert.IsFalse(account1.Credentials.IsAnonymous); - Assert.IsFalse(account1.Credentials.IsSAS); - Assert.IsTrue(account1.Credentials.IsSharedKey); - Assert.AreEqual(emptyKeyValueAsString, Convert.ToBase64String(account1.Credentials.ExportKey())); - - CloudStorageAccount account2 = CloudStorageAccount.Parse(emptyKeyConnectionString); - Assert.AreEqual(emptyKeyConnectionString, account2.ToString(true)); - Assert.IsNotNull(account2.Credentials); - Assert.AreEqual(accountName, account2.Credentials.AccountName); - Assert.IsFalse(account2.Credentials.IsAnonymous); - Assert.IsFalse(account2.Credentials.IsSAS); - Assert.IsTrue(account2.Credentials.IsSharedKey); - Assert.AreEqual(emptyKeyValueAsString, Convert.ToBase64String(account2.Credentials.ExportKey())); - - CloudStorageAccount account3; - bool isValidAccount3 = CloudStorageAccount.TryParse(emptyKeyConnectionString, out account3); - Assert.IsTrue(isValidAccount3); - Assert.IsNotNull(account3); - Assert.AreEqual(emptyKeyConnectionString, account3.ToString(true)); - Assert.IsNotNull(account3.Credentials); - Assert.AreEqual(accountName, account3.Credentials.AccountName); - Assert.IsFalse(account3.Credentials.IsAnonymous); - Assert.IsFalse(account3.Credentials.IsSAS); - Assert.IsTrue(account3.Credentials.IsSharedKey); - Assert.AreEqual(emptyKeyValueAsString, Convert.ToBase64String(account3.Credentials.ExportKey())); - - StorageCredentials credentials2 = new StorageCredentials(accountName, keyValue); - Assert.AreEqual(accountName, credentials2.AccountName); - Assert.IsFalse(credentials2.IsAnonymous); - Assert.IsFalse(credentials2.IsSAS); - Assert.IsTrue(credentials2.IsSharedKey); - Assert.AreEqual(keyValue, Convert.ToBase64String(credentials2.ExportKey())); - - credentials2.UpdateKey(emptyKeyValueAsString, null); - Assert.AreEqual(emptyKeyValueAsString, Convert.ToBase64String(credentials2.ExportKey())); - -#if !WINDOWS_RT - byte[] emptyKeyValueAsByteArray = new byte[0]; - - StorageCredentials credentials3 = new StorageCredentials(accountName, keyValue); - Assert.AreEqual(accountName, credentials3.AccountName); - Assert.IsFalse(credentials3.IsAnonymous); - Assert.IsFalse(credentials3.IsSAS); - Assert.IsTrue(credentials3.IsSharedKey); - Assert.AreEqual(keyValue, Convert.ToBase64String(credentials3.ExportKey())); - - credentials3.UpdateKey(emptyKeyValueAsByteArray, null); - Assert.AreEqual(Convert.ToBase64String(emptyKeyValueAsByteArray), Convert.ToBase64String(credentials3.ExportKey())); -#endif - } - - [TestMethod] - /// [Description("CloudStorageAccount object with a null key value.")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsNullKeyValue() - { - string accountName = TestBase.TargetTenantConfig.AccountName; - string keyValue = TestBase.TargetTenantConfig.AccountKey; - string nullKeyValueAsString = null; - - TestHelper.ExpectedException(() => - { - StorageCredentials credentials1 = new StorageCredentials(accountName, nullKeyValueAsString); - }, "Cannot create key with a null value."); - - StorageCredentials credentials2 = new StorageCredentials(accountName, keyValue); - Assert.AreEqual(accountName, credentials2.AccountName); - Assert.IsFalse(credentials2.IsAnonymous); - Assert.IsFalse(credentials2.IsSAS); - Assert.IsTrue(credentials2.IsSharedKey); - Assert.AreEqual(keyValue, Convert.ToBase64String(credentials2.ExportKey())); - - TestHelper.ExpectedException(() => - { - credentials2.UpdateKey(nullKeyValueAsString, null); - }, "Cannot update key with a null string value."); - -#if !WINDOWS_RT - byte[] nullKeyValueAsByteArray = null; - - StorageCredentials credentials3 = new StorageCredentials(accountName, keyValue); - Assert.AreEqual(accountName, credentials3.AccountName); - Assert.IsFalse(credentials3.IsAnonymous); - Assert.IsFalse(credentials3.IsSAS); - Assert.IsTrue(credentials3.IsSharedKey); - Assert.AreEqual(keyValue, Convert.ToBase64String(credentials3.ExportKey())); - - TestHelper.ExpectedException(() => - { - credentials3.UpdateKey(nullKeyValueAsByteArray, null); - }, "Cannot update key with a null byte array value."); -#endif - } - - [TestMethod] - /// [Description("Compare credentials for equality")] - [TestCategory(ComponentCategory.Auth)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageCredentialsEquality() - { - StorageCredentials credSharedKey1 = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - StorageCredentials credSharedKey2 = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - StorageCredentials credSharedKey3 = new StorageCredentials(TestBase.TargetTenantConfig.AccountName + "1", TestBase.TargetTenantConfig.AccountKey); - StorageCredentials credSharedKey4 = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, Convert.ToBase64String(new byte[] { 0, 1, 2 })); - StorageCredentials credSAS1 = new StorageCredentials(token); - StorageCredentials credSAS2 = new StorageCredentials(token); - StorageCredentials credSAS3 = new StorageCredentials(token + "1"); - StorageCredentials credAnonymous1 = new StorageCredentials(); - StorageCredentials credAnonymous2 = new StorageCredentials(); - - Assert.IsTrue(credSharedKey1.Equals(credSharedKey2)); - Assert.IsFalse(credSharedKey1.Equals(credSharedKey3)); - Assert.IsFalse(credSharedKey1.Equals(credSharedKey4)); - Assert.IsTrue(credSAS1.Equals(credSAS2)); - Assert.IsFalse(credSAS1.Equals(credSAS3)); - Assert.IsTrue(credAnonymous1.Equals(credAnonymous2)); - Assert.IsFalse(credSharedKey1.Equals(credSAS1)); - Assert.IsFalse(credSharedKey1.Equals(credAnonymous1)); - Assert.IsFalse(credSAS1.Equals(credAnonymous1)); - } - - private void AccountsAreEqual(CloudStorageAccount a, CloudStorageAccount b) - { - // endpoints are the same - Assert.AreEqual(a.BlobEndpoint, b.BlobEndpoint); - Assert.AreEqual(a.QueueEndpoint, b.QueueEndpoint); - Assert.AreEqual(a.TableEndpoint, b.TableEndpoint); - - // seralized representatons are the same. - string aToStringNoSecrets = a.ToString(); - string aToStringWithSecrets = a.ToString(true); - string bToStringNoSecrets = b.ToString(false); - string bToStringWithSecrets = b.ToString(true); - Assert.AreEqual(aToStringNoSecrets, bToStringNoSecrets, false); - Assert.AreEqual(aToStringWithSecrets, bToStringWithSecrets, false); - - // credentials are the same - if (a.Credentials != null && b.Credentials != null) - { - Assert.AreEqual(a.Credentials.IsAnonymous, b.Credentials.IsAnonymous); - Assert.AreEqual(a.Credentials.IsSAS, b.Credentials.IsSAS); - Assert.AreEqual(a.Credentials.IsSharedKey, b.Credentials.IsSharedKey); - - // make sure - if (!a.Credentials.IsAnonymous && - a.Credentials != CloudStorageAccount.DevelopmentStorageAccount.Credentials && - b.Credentials != CloudStorageAccount.DevelopmentStorageAccount.Credentials) - { - Assert.AreNotEqual(aToStringWithSecrets, bToStringNoSecrets, true); - } - } - else if (a.Credentials == null && b.Credentials == null) - { - return; - } - else - { - Assert.Fail("credentials mismatch"); - } - } - - [TestMethod] - /// [Description("DevStore account")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevelopmentStorageAccount() - { - CloudStorageAccount devstoreAccount = CloudStorageAccount.DevelopmentStorageAccount; - Assert.AreEqual(devstoreAccount.BlobEndpoint, new Uri("http://127.0.0.1:10000/devstoreaccount1")); - Assert.AreEqual(devstoreAccount.QueueEndpoint, new Uri("http://127.0.0.1:10001/devstoreaccount1")); - Assert.AreEqual(devstoreAccount.TableEndpoint, new Uri("http://127.0.0.1:10002/devstoreaccount1")); - string devstoreAccountToStringWithSecrets = devstoreAccount.ToString(true); - CloudStorageAccount testAccount = CloudStorageAccount.Parse(devstoreAccountToStringWithSecrets); - - // make sure it round trips - AccountsAreEqual(testAccount, devstoreAccount); - CloudStorageAccount acct; - if (!CloudStorageAccount.TryParse(devstoreAccountToStringWithSecrets, out acct)) - { - Assert.Fail("Expected TryParse success."); - } - } - - [TestMethod] - /// [Description("Regular account with HTTP")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDefaultStorageAccountWithHttp() - { - StorageCredentials cred = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(cred, false); - Assert.AreEqual(cloudStorageAccount.BlobEndpoint, - new Uri(String.Format("http://{0}.blob.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - Assert.AreEqual(cloudStorageAccount.QueueEndpoint, - new Uri(String.Format("http://{0}.queue.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - Assert.AreEqual(cloudStorageAccount.TableEndpoint, - new Uri(String.Format("http://{0}.table.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - string cloudStorageAccountToStringNoSecrets = cloudStorageAccount.ToString(); - string cloudStorageAccountToStringWithSecrets = cloudStorageAccount.ToString(true); - CloudStorageAccount testAccount = CloudStorageAccount.Parse(cloudStorageAccountToStringWithSecrets); - // make sure it round trips - AccountsAreEqual(testAccount, cloudStorageAccount); - } - - [TestMethod] - /// [Description("Regular account with HTTPS")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDefaultStorageAccountWithHttps() - { - StorageCredentials cred = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(cred, true); - Assert.AreEqual(cloudStorageAccount.BlobEndpoint, - new Uri(String.Format("https://{0}.blob.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - Assert.AreEqual(cloudStorageAccount.QueueEndpoint, - new Uri(String.Format("https://{0}.queue.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - Assert.AreEqual(cloudStorageAccount.TableEndpoint, - new Uri(String.Format("https://{0}.table.core.windows.net", TestBase.TargetTenantConfig.AccountName))); - - string cloudStorageAccountToStringWithSecrets = cloudStorageAccount.ToString(true); - CloudStorageAccount testAccount = CloudStorageAccount.Parse(cloudStorageAccountToStringWithSecrets); - // make sure it round trips - AccountsAreEqual(testAccount, cloudStorageAccount); - } - - [TestMethod] - /// [Description("Regular account with HTTP")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountEndpointSuffix() - { - const string TestEndpointSuffix = "fake.endpoint.suffix"; - - CloudStorageAccount testAccount = - CloudStorageAccount.Parse( - string.Format( - "DefaultEndpointsProtocol=http;AccountName={0};AccountKey={1};EndpointSuffix={2};", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey, - TestEndpointSuffix)); - - StorageCredentials cred = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(cred, TestEndpointSuffix, false); - - // make sure it round trips - this.AccountsAreEqual(testAccount, cloudStorageAccount); - } - - [TestMethod] - /// [Description("Regular account with HTTP")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountEndpointSuffixWithBlob() - { - const string TestEndpointSuffix = "fake.endpoint.suffix"; - const string AlternateBlobEndpoint = "http://blob.other.endpoint/"; - - CloudStorageAccount testAccount = - CloudStorageAccount.Parse( - string.Format( - "DefaultEndpointsProtocol=http;AccountName={0};AccountKey={1};EndpointSuffix={2};BlobEndpoint={3}", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey, - TestEndpointSuffix, - AlternateBlobEndpoint)); - - CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(testAccount.ToString(true)); - - // make sure it round trips - this.AccountsAreEqual(testAccount, cloudStorageAccount); - } - - [TestMethod] - /// [Description("Regular account with HTTP")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountConnectionStringRoundtrip() - { - string accountString1 = - string.Format( - "DefaultEndpointsProtocol=http;AccountName={0};AccountKey={1};EndpointSuffix={2};", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey, - "fake.endpoint.suffix"); - - string accountString2 = - string.Format( - "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey); - - string accountString3 = - string.Format( - "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};QueueEndpoint={2}", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey, - "https://alternate.queue.endpoint/"); - - string accountString4 = - string.Format( - "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2};QueueEndpoint={3}", - TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey, - "fake.endpoint.suffix", - "https://alternate.queue.endpoint/"); - - connectionStringRoundtripHelper(accountString1); - connectionStringRoundtripHelper(accountString2); - connectionStringRoundtripHelper(accountString3); - connectionStringRoundtripHelper(accountString4); - } - - private void connectionStringRoundtripHelper(string accountString) - { - CloudStorageAccount originalAccount = CloudStorageAccount.Parse(accountString); - CloudStorageAccount copiedAccount = CloudStorageAccount.Parse(originalAccount.ToString(true)); - - // make sure it round trips - this.AccountsAreEqual(originalAccount, copiedAccount); - } - - [TestMethod] - /// [Description("Service client creation methods")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountClientMethods() - { - CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount; - CloudBlobClient blob = account.CreateCloudBlobClient(); - CloudQueueClient queue = account.CreateCloudQueueClient(); - CloudTableClient table = account.CreateCloudTableClient(); - - // check endpoints - Assert.AreEqual(account.BlobEndpoint, blob.BaseUri, "Blob endpoint doesn't match account"); - Assert.AreEqual(account.QueueEndpoint, queue.BaseUri, "Queue endpoint doesn't match account"); - Assert.AreEqual(account.TableEndpoint, table.BaseUri, "Table endpoint doesn't match account"); - - // check creds - Assert.AreEqual(account.Credentials, blob.Credentials, "Blob creds don't match account"); - Assert.AreEqual(account.Credentials, queue.Credentials, "Queue creds don't match account"); - Assert.AreEqual(account.Credentials, table.Credentials, "Table creds don't match account"); - } - - [TestMethod] - /// [Description("Service client creation methods")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountClientUriVerify() - { - StorageCredentials cred = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, TestBase.TargetTenantConfig.AccountKey); - CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(cred, true); - - CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("container1"); - Assert.AreEqual(cloudStorageAccount.BlobEndpoint.ToString() + "container1", container.Uri.ToString()); - - CloudQueueClient queueClient = cloudStorageAccount.CreateCloudQueueClient(); - CloudQueue queue = queueClient.GetQueueReference("queue1"); - Assert.AreEqual(cloudStorageAccount.QueueEndpoint.ToString() + "queue1", queue.Uri.ToString()); - - CloudTableClient tableClient = cloudStorageAccount.CreateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("table1"); - Assert.AreEqual(cloudStorageAccount.TableEndpoint.ToString() + "table1", table.Uri.ToString()); - } - - [TestMethod] - /// [Description("TryParse should return false for invalid connection strings")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountTryParseNullEmpty() - { - CloudStorageAccount account; - // TryParse should not throw exception when passing in null or empty string - Assert.IsFalse(CloudStorageAccount.TryParse(null, out account)); - Assert.IsFalse(CloudStorageAccount.TryParse(string.Empty, out account)); - } - - [TestMethod] - /// [Description("UseDevelopmentStorage=false should fail")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStoreNonTrueFails() - { - CloudStorageAccount account; - - Assert.IsFalse(CloudStorageAccount.TryParse("UseDevelopmentStorage=false", out account)); - } - - [TestMethod] - /// [Description("UseDevelopmentStorage should fail when used with an account name")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStorePlusAccountFails() - { - CloudStorageAccount account; - - Assert.IsFalse(CloudStorageAccount.TryParse("UseDevelopmentStorage=false;AccountName=devstoreaccount1", out account)); - } - - [TestMethod] - /// [Description("UseDevelopmentStorage should fail when used with a custom endpoint")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStorePlusEndpointFails() - { - CloudStorageAccount account; - - Assert.IsFalse(CloudStorageAccount.TryParse("UseDevelopmentStorage=false;BlobEndpoint=http://127.0.0.1:1000/devstoreaccount1", out account)); - } - - [TestMethod] - /// [Description("Custom endpoints")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDefaultEndpointOverride() - { - CloudStorageAccount account; - - Assert.IsTrue(CloudStorageAccount.TryParse("DefaultEndpointsProtocol=http;BlobEndpoint=http://customdomain.com/;AccountName=asdf;AccountKey=123=", out account)); - Assert.AreEqual(new Uri("http://customdomain.com/"), account.BlobEndpoint); - } - - [TestMethod] - /// [Description("Use DevStore with a proxy")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStoreProxyUri() - { - CloudStorageAccount account; - - Assert.IsTrue(CloudStorageAccount.TryParse("UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler", out account)); - Assert.AreEqual(new Uri("http://ipv4.fiddler:10000/devstoreaccount1"), account.BlobEndpoint); - Assert.AreEqual(new Uri("http://ipv4.fiddler:10001/devstoreaccount1"), account.QueueEndpoint); - Assert.AreEqual(new Uri("http://ipv4.fiddler:10002/devstoreaccount1"), account.TableEndpoint); - } - - [TestMethod] - /// [Description("ToString method for DevStore account should not return endpoint info")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStoreRoundtrip() - { - string accountString = "UseDevelopmentStorage=true"; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method for DevStore account with a proxy should not return endpoint info")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDevStoreProxyRoundtrip() - { - string accountString = "UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler/"; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method for regular account should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountDefaultCloudRoundtrip() - { - string accountString = "DefaultEndpointsProtocol=http;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method for custom endpoints should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountExplicitCloudRoundtrip() - { - string accountString = "BlobEndpoint=https://blobs/;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method for anonymous credentials should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountAnonymousRoundtrip() - { - string accountString = "BlobEndpoint=http://blobs/"; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - - CloudStorageAccount account = new CloudStorageAccount(null, new Uri("http://blobs/"), null, null); - - AccountsAreEqual(account, CloudStorageAccount.Parse(account.ToString(true))); - } - - [TestMethod] - /// [Description("Parse method should ignore empty values")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountEmptyValues() - { - string accountString = ";BlobEndpoint=http://blobs/;;AccountName=test;;AccountKey=abc=;"; - string validAccountString = "BlobEndpoint=http://blobs/;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(validAccountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method with custom blob endpoint should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountJustBlobToString() - { - string accountString = "BlobEndpoint=http://blobs/;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method with custom queue endpoint should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountJustQueueToString() - { - string accountString = "QueueEndpoint=http://queue/;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("ToString method with custom table endpoint should return the same connection string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountJustTableToString() - { - string accountString = "TableEndpoint=http://table/;AccountName=test;AccountKey=abc="; - - Assert.AreEqual(accountString, CloudStorageAccount.Parse(accountString).ToString(true)); - } - - [TestMethod] - /// [Description("Exporting account key should be possible both as a byte array and a Base64 encoded string")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudStorageAccountExportKey() - { - string accountKeyString = "abc2564="; - string accountString = "BlobEndpoint=http://blobs/;AccountName=test;AccountKey=" + accountKeyString; - CloudStorageAccount account = CloudStorageAccount.Parse(accountString); - StorageCredentials accountAndKey = (StorageCredentials)account.Credentials; - string key = accountAndKey.ExportBase64EncodedKey(); - Assert.AreEqual(accountKeyString, key); - - byte[] keyBytes = accountAndKey.ExportKey(); - byte[] expectedKeyBytes = Convert.FromBase64String(accountKeyString); - for (int i = 0; i < expectedKeyBytes.Length; i++) - { - Assert.AreEqual(expectedKeyBytes[i], keyBytes[i]); - } - Assert.AreEqual(expectedKeyBytes.Length, keyBytes.Length); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/TestLogListener.Common.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/TestLogListener.Common.cs deleted file mode 100644 index 7f70003d5dc7b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/TestLogListener.Common.cs +++ /dev/null @@ -1,163 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - public partial class TestLogListener - { -#if !WINDOWS_PHONE - private const int LogEntryFieldCount = 2; - - private static IList requestIDs = new List(); - private static volatile int errorCount = 0; - private static volatile int warningCount = 0; - private static volatile int informationalCount = 0; - private static volatile int verboseCount = 0; - private static volatile bool isCollecting = false; - - internal static string LastRequestID - { - get - { - lock (TestLogListener.requestIDs) - { - return TestLogListener.requestIDs[TestLogListener.requestIDs.Count - 1]; - } - } - } - - internal static int RequestCount - { - get - { - lock (TestLogListener.requestIDs) - { - return TestLogListener.requestIDs.Count; - } - } - } - - internal static int ErrorCount - { - get - { - return TestLogListener.errorCount; - } - } - - internal static int WarningCount - { - get - { - return TestLogListener.warningCount; - } - } - - internal static int InformationalCount - { - get - { - return TestLogListener.informationalCount; - } - } - - internal static int VerboseCount - { - get - { - return TestLogListener.verboseCount; - } - } - - internal static void Start() - { - TestLogListener.isCollecting = true; - } - - internal static void Restart() - { - TestLogListener.Stop(); - - lock (TestLogListener.requestIDs) - { - TestLogListener.requestIDs.Clear(); - TestLogListener.errorCount = 0; - TestLogListener.warningCount = 0; - TestLogListener.informationalCount = 0; - TestLogListener.verboseCount = 0; - } - - TestLogListener.Start(); - } - - internal static void Stop() - { - TestLogListener.isCollecting = false; - } - - private static void ProcessMessage(LogLevel level, string message) - { - if (!TestLogListener.isCollecting) - { - return; - } - - string[] line = message.Split(new char[] { ':' }, TestLogListener.LogEntryFieldCount); - if (line.Length == TestLogListener.LogEntryFieldCount) - { - lock (TestLogListener.requestIDs) - { - if (!TestLogListener.requestIDs.Contains(line[0])) - { - TestLogListener.requestIDs.Add(line[0]); - } - - switch (level) - { - case LogLevel.Error: - TestLogListener.errorCount++; - break; - - case LogLevel.Warning: - TestLogListener.warningCount++; - break; - - case LogLevel.Informational: - TestLogListener.informationalCount++; - break; - - case LogLevel.Verbose: - TestLogListener.verboseCount++; - break; - - default: - throw new InvalidOperationException(message); - } - } - } - else - { - throw new InvalidOperationException(message); - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/UtilityTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/UtilityTests.cs deleted file mode 100644 index bdbb9a207e4f5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Core/UtilityTests.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.WindowsAzure.Storage.Core.Util; - using System; - using System.Collections.Generic; - -#if WINDOWS_DESKTOP - using Microsoft.VisualStudio.TestTools.UnitTesting; -#else - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - - [TestClass] - public class UtilityTests : TestBase - { - [TestMethod] - /// [Description("Test to ensure HttpWebUtility.ParseQueryString works like HttpUtility.ParseQueryString")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ParseQueryStringTest() - { - IDictionary dictionary = HttpWebUtility.ParseQueryString("?a=1&b&=c&d=&a=&d=2&&&d=&d="); - Assert.AreEqual(3, dictionary.Count); - Assert.AreEqual("b,c,,", dictionary[""]); - Assert.AreEqual("1,", dictionary["a"]); - Assert.AreEqual(",2,,", dictionary["d"]); - - dictionary = HttpWebUtility.ParseQueryString("a=1&b"); - Assert.AreEqual(2, dictionary.Count); - Assert.AreEqual("b", dictionary[""]); - Assert.AreEqual("1", dictionary["a"]); - - dictionary = HttpWebUtility.ParseQueryString(""); - Assert.AreEqual(0, dictionary.Count); - - dictionary = HttpWebUtility.ParseQueryString("?"); - Assert.AreEqual(0, dictionary.Count); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/GeneralTestSample.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/GeneralTestSample.cs deleted file mode 100644 index b5e5be339daf9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/GeneralTestSample.cs +++ /dev/null @@ -1,40 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -namespace Microsoft.WindowsAzure.Storage -{ - [TestClass] - public class GeneralTestSample : TestBase - { - [TestMethod] - /// [Description("A sample test to show how to skip cloud env.")] - [TestCategory("SampleTest")] - [TestCategory("SampleTest")] - [TestCategory("NonSmoke")] - public void SkipForCloudTestSample() - { - // This is also an example to show how the two test projects share the same unit test code. - TestHelper.ValidateIfTestSupportTargetTenant(TenantType.DevStore | TenantType.DevFabric); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/MockBufferManager.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/MockBufferManager.cs deleted file mode 100644 index e139808e90d50..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/MockBufferManager.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Blob; -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -namespace Microsoft.WindowsAzure.Storage -{ - public class MockBufferManager : IBufferManager - { - private int defaultBufferSize = 0; - - public MockBufferManager(int defaultBufferSize) - { - this.defaultBufferSize = defaultBufferSize; - } - - private int outstandingBufferCount = 0; - public int OutstandingBufferCount - { - get - { - return Interlocked.CompareExchange(ref outstandingBufferCount, 0, 0); - } - set - { - Interlocked.Exchange(ref outstandingBufferCount, value); - } - } - - public void ReturnBuffer(byte[] buffer) - { - Interlocked.Decrement(ref outstandingBufferCount); - // no op - } - - public byte[] TakeBuffer(int bufferSize) - { - Interlocked.Increment(ref outstandingBufferCount); - return new byte[bufferSize]; - } - - public int GetDefaultBufferSize() - { - return this.defaultBufferSize; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Queue/QueueTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Queue/QueueTestBase.cs deleted file mode 100644 index e1608cf6529b0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Queue/QueueTestBase.cs +++ /dev/null @@ -1,33 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - public class QueueTestBase : TestBase - { - /// - /// Generate the random queue name for the test. - /// - /// - internal static string GenerateNewQueueName() - { - return "libqueuetest" + Guid.NewGuid().ToString("N"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Readme.txt b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Readme.txt deleted file mode 100644 index e9c7885b42382..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Readme.txt +++ /dev/null @@ -1,18 +0,0 @@ -Generally speaking, every test method is written with a brief description and 4 test categories: -1) The first test category defines which component to test in this method. The valid options are Auth/Core/RetryPolicies/Blob/Queue/Table. -2) The second test category defines it�s a UnitTest or FunctionalTest. The valid options are are UnitTest/FunctionalTest/StressTest. -3) The third test category defines if it�s a smoke test. We need to at least run all smoke tests before checkin. The valid options are Smoke/NonSmoke. -4) The fourth test category defines the target test environments for this test case. Note that a test case can have up to 3 target test environments(DevStore/DevFabric/Cloud). - The valid options are DevStore/DevFabric/Cloud. - -The following is a test example. - [TestMethod] - [Description("A test verifies all the constructor of the class StorageCredentials.")] - [TestCategory("Auth")] - [TestCategory("UnitTest")] - [TestCategory("Smoke")] - [TestCategory("DevStore"), TestCategory("DevFabric"), TestCategory("Cloud")] - public void StorageCredentialsSampleTestMethod() - { - ... - } \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/BaseEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/BaseEntity.cs deleted file mode 100644 index 14a5630b5082d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/BaseEntity.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - public class BaseEntity : TableEntity - { - public BaseEntity() - { - } - - public BaseEntity(string pk, string rk) - : base(pk, rk) - { - } - - public void Populate() - { - this.foo = "bar"; - this.A = "a"; - this.B = "b"; - this.C = "c"; - this.D = "d"; - } - - public string foo { get; set; } - public string A { get; set; } - public string B { get; set; } - public string C { get; set; } - public string D { get; set; } - - public void Validate() - { - Assert.AreEqual(this.foo, "bar"); - Assert.AreEqual(this.A, "a"); - Assert.AreEqual(this.B, "b"); - Assert.AreEqual(this.C, "c"); - Assert.AreEqual(this.D, "d"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ComplexEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ComplexEntity.cs deleted file mode 100644 index 6cce08843ccce..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ComplexEntity.cs +++ /dev/null @@ -1,342 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif -using System; - -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - public class ComplexEntity : TableEntity - { - public const int NumberOfNonNullProperties = 26; - - public ComplexEntity() - : base() - { - } - - public ComplexEntity(string pk, string rk) - : base(pk, rk) - { - } - - public CloudStorageAccount UnSupportedProperty { get; set; } - - private DateTimeOffset? dateTimeOffsetNull = null; - public DateTimeOffset? DateTimeOffsetNull - { - get { return dateTimeOffsetNull; } - set { dateTimeOffsetNull = value; } - } - - private DateTimeOffset? dateTimeOffsetN = DateTimeOffset.Now; - public DateTimeOffset? DateTimeOffsetN - { - get { return dateTimeOffsetN; } - set { dateTimeOffsetN = value; } - } - - private DateTimeOffset dateTimeOffset = DateTimeOffset.Now; - public DateTimeOffset DateTimeOffset - { - get { return dateTimeOffset; } - set { dateTimeOffset = value; } - } - - private DateTime? dateTimeNull = null; - public DateTime? DateTimeNull - { - get { return dateTimeNull; } - set { dateTimeNull = value; } - } - - private DateTime? dateTimeN = DateTime.UtcNow; - public DateTime? DateTimeN - { - get { return dateTimeN; } - set { dateTimeN = value; } - } - - private DateTime dateTime = DateTime.UtcNow; - public DateTime DateTime - { - get { return dateTime; } - set { dateTime = value; } - } - - private Boolean? boolObjNull = null; - public Boolean? BoolNull - { - get { return boolObjNull; } - set { boolObjNull = value; } - } - - private Boolean? boolObjN = false; - public Boolean? BoolN - { - get { return boolObjN; } - set { boolObjN = value; } - } - - private Boolean boolObj = false; - public Boolean Bool - { - get { return boolObj; } - set { boolObj = value; } - } - - private bool? boolPrimitiveNull = null; - public bool? BoolPrimitiveNull - { - get { return boolPrimitiveNull; } - set { boolPrimitiveNull = value; } - } - - private bool? boolPrimitiveN = false; - public bool? BoolPrimitiveN - { - get { return boolPrimitiveN; } - set { boolPrimitiveN = value; } - } - - private bool boolPrimitive = false; - public bool BoolPrimitive - { - get { return boolPrimitive; } - set { boolPrimitive = value; } - } - - private Byte[] binary = new Byte[] { 1, 2, 3, 4 }; - public Byte[] Binary - { - get { return binary; } - set { binary = value; } - } - - private Byte[] binaryNull = null; - public Byte[] BinaryNull - { - get { return binaryNull; } - set { binaryNull = value; } - } - - private byte[] binaryPrimitive = new byte[] { 1, 2, 3, 4 }; - public byte[] BinaryPrimitive - { - get { return binaryPrimitive; } - set { binaryPrimitive = value; } - } - - private double? doublePrimitiveNull = null; - public double? DoublePrimitiveNull - { - get { return doublePrimitiveNull; } - set { doublePrimitiveNull = value; } - } - - private double? doublePrimitiveN = (double)1234.1234; - public double? DoublePrimitiveN - { - get { return doublePrimitiveN; } - set { doublePrimitiveN = value; } - } - - private double doublePrimitive = (double)1234.1234; - public double DoublePrimitive - { - get { return doublePrimitive; } - set { doublePrimitive = value; } - } - - private Double? doubleOBjNull = null; - public Double? DoubleNull - { - get { return doubleOBjNull; } - set { doubleOBjNull = value; } - } - - private Double? doubleOBjN = (Double)1234.1234; - public Double? DoubleN - { - get { return doubleOBjN; } - set { doubleOBjN = value; } - } - - private Double doubleOBj = (Double)1234.1234; - public Double Double - { - get { return doubleOBj; } - set { doubleOBj = value; } - } - - private Guid? guidNull = null; - public Guid? GuidNull - { - get { return guidNull; } - set { guidNull = value; } - } - - private Guid? guidN = Guid.NewGuid(); - public Guid? GuidN - { - get { return guidN; } - set { guidN = value; } - } - - private Guid guid = Guid.NewGuid(); - public Guid Guid - { - get { return guid; } - set { guid = value; } - } - - private int? integerPrimitiveNull = null; - public int? IntegerPrimitiveNull - { - get { return integerPrimitiveNull; } - set { integerPrimitiveNull = value; } - } - - private int? integerPrimitiveN = 1234; - public int? IntegerPrimitiveN - { - get { return integerPrimitiveN; } - set { integerPrimitiveN = value; } - } - - private int integerPrimitive = 1234; - public int IntegerPrimitive - { - get { return integerPrimitive; } - set { integerPrimitive = value; } - } - - private Int32? int32Null = null; - public Int32? Int32Null - { - get { return int32Null; } - set { int32Null = value; } - } - - private Int32? int32N = 1234; - public Int32? Int32N - { - get { return int32N; } - set { int32N = value; } - } - - private Int32 int32 = 1234; - public Int32 Int32 - { - get { return int32; } - set { int32 = value; } - } - - private long? longPrimitiveNull = null; - public long? LongPrimitiveNull - { - get { return longPrimitiveNull; } - set { longPrimitiveNull = value; } - } - - private long? longPrimitiveN = 123456789012; - public long? LongPrimitiveN - { - get { return longPrimitiveN; } - set { longPrimitiveN = value; } - } - - private long longPrimitive = 123456789012; - public long LongPrimitive - { - get { return longPrimitive; } - set { longPrimitive = value; } - } - - private Int64? int64Null = null; - public Int64? Int64Null - { - get { return int64Null; } - set { int64Null = value; } - } - - private Int64? int64N = 123456789012; - public Int64? Int64N - { - get { return int64N; } - set { int64N = value; } - } - - private Int64 int64 = 123456789012; - public Int64 Int64 - { - get { return int64; } - set { int64 = value; } - } - - private string stringObj = "test"; - public string String - { - get { return stringObj; } - set { stringObj = value; } - } - - public static void AssertEquality(ComplexEntity a, ComplexEntity b) - { - Assert.AreEqual(a.String, b.String); - Assert.AreEqual(a.Int64, b.Int64); - Assert.AreEqual(a.Int64N, b.Int64N); - Assert.AreEqual(a.Int64Null, b.Int64Null); - Assert.AreEqual(a.LongPrimitive, b.LongPrimitive); - Assert.AreEqual(a.LongPrimitiveN, b.LongPrimitiveN); - Assert.AreEqual(a.LongPrimitiveNull, b.LongPrimitiveNull); - Assert.AreEqual(a.Int32, b.Int32); - Assert.AreEqual(a.Int32N, b.Int32N); - Assert.AreEqual(a.Int32Null, b.Int32Null); - Assert.AreEqual(a.IntegerPrimitive, b.IntegerPrimitive); - Assert.AreEqual(a.integerPrimitiveN, b.IntegerPrimitiveN); - Assert.AreEqual(a.IntegerPrimitiveNull, b.IntegerPrimitiveNull); - Assert.AreEqual(a.Guid, b.Guid); - Assert.AreEqual(a.GuidN, b.GuidN); - Assert.AreEqual(a.GuidNull, b.GuidNull); - Assert.AreEqual(a.Double, b.Double); - Assert.AreEqual(a.DoubleN, b.DoubleN); - Assert.AreEqual(a.DoubleNull, b.DoubleNull); - Assert.AreEqual(a.DoublePrimitive, b.DoublePrimitive); - Assert.AreEqual(a.DoublePrimitiveN, b.DoublePrimitiveN); - Assert.AreEqual(a.DoublePrimitiveNull, b.DoublePrimitiveNull); - Assert.AreEqual(a.BinaryPrimitive, b.BinaryPrimitive); - Assert.AreEqual(a.Binary, b.Binary); - Assert.AreEqual(a.BoolPrimitive, b.BoolPrimitive); - Assert.AreEqual(a.BoolPrimitiveN, b.BoolPrimitiveN); - Assert.AreEqual(a.BoolPrimitiveNull, b.BoolPrimitiveNull); - Assert.AreEqual(a.Bool, b.Bool); - Assert.AreEqual(a.BoolN, b.BoolN); - Assert.AreEqual(a.BoolNull, b.BoolNull); - Assert.AreEqual(a.DateTimeOffsetN, b.DateTimeOffsetN); - Assert.AreEqual(a.DateTimeOffset, b.DateTimeOffset); - Assert.AreEqual(a.DateTimeOffsetNull, b.DateTimeOffsetNull); - Assert.AreEqual(a.DateTime, b.DateTime); - Assert.AreEqual(a.DateTimeN, b.DateTimeN); - Assert.AreEqual(a.DateTimeNull, b.DateTimeNull); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/IgnoreEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/IgnoreEntity.cs deleted file mode 100644 index a686676cab738..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/IgnoreEntity.cs +++ /dev/null @@ -1,127 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - public class IgnoreEntity : TableEntity - { - public const int NumberOfNonNullProperties = 26; - - public IgnoreEntity() - : base() - { - } - - public IgnoreEntity(string pk, string rk) - : base(pk, rk) - { - } - - private DateTimeOffset? dateTimeOffsetNull = null; - [IgnorePropertyAttribute] - public DateTimeOffset? DateTimeOffsetNull - { - get { return dateTimeOffsetNull; } - set { dateTimeOffsetNull = value; } - } - - private DateTimeOffset? dateTimeOffsetN = DateTimeOffset.Now; - public DateTimeOffset? DateTimeOffsetN - { - get { return dateTimeOffsetN; } - set { dateTimeOffsetN = value; } - } - - private DateTimeOffset dateTimeOffset = DateTimeOffset.Now; - [IgnorePropertyAttribute] - public DateTimeOffset DateTimeOffset - { - get { return dateTimeOffset; } - set { dateTimeOffset = value; } - } - - private DateTime? dateTimeNull = null; - public DateTime? DateTimeNull - { - get { return dateTimeNull; } - set { dateTimeNull = value; } - } - - private DateTime? dateTimeN = DateTime.UtcNow; - public DateTime? DateTimeN - { - get { return dateTimeN; } - set { dateTimeN = value; } - } - - private DateTime dateTime = DateTime.UtcNow; - public DateTime DateTime - { - get { return dateTime; } - set { dateTime = value; } - } - - private Boolean? boolObjNull = null; - public Boolean? BoolNull - { - get { return boolObjNull; } - set { boolObjNull = value; } - } - - private Boolean? boolObjN = false; - public Boolean? BoolN - { - get { return boolObjN; } - set { boolObjN = value; } - } - - private Boolean boolObj = false; - [IgnorePropertyAttribute] - public Boolean Bool - { - get { return boolObj; } - set { boolObj = value; } - } - - private bool? boolPrimitiveNull = null; - [IgnorePropertyAttribute] - public bool? BoolPrimitiveNull - { - get { return boolPrimitiveNull; } - set { boolPrimitiveNull = value; } - } - - private bool? boolPrimitiveN = false; - public bool? BoolPrimitiveN - { - get { return boolPrimitiveN; } - set { boolPrimitiveN = value; } - } - - private bool boolPrimitive = false; - public bool BoolPrimitive - { - get { return boolPrimitive; } - set { boolPrimitive = value; } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/POCOAdapter.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/POCOAdapter.cs deleted file mode 100644 index 9027da9a9f7c4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/POCOAdapter.cs +++ /dev/null @@ -1,78 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - public class POCOAdapter : ITableEntity - { - public POCOAdapter(ShapeEntity shape) - { - this.Shape = shape; - } - - public POCOAdapter(ShapeEntity shape, string partitionKey, string rowKey) - { - this.PartitionKey = partitionKey; - this.RowKey = rowKey; - this.Shape = shape; - } - - #region ITableEntity Implementation - - /// - /// Gets or sets the entity's partition key. - /// - /// The partition key of the entity. - public string PartitionKey { get; set; } - - /// - /// Gets or sets the entity's row key. - /// - /// The row key of the entity. - public string RowKey { get; set; } - - /// - /// Gets or sets the entity's timestamp. - /// - /// The timestamp of the entity. - public DateTimeOffset Timestamp { get; set; } - - /// - /// Gets or sets the entity's current ETag. Set this value to '*' in order to blindly overwrite an entity as part of an update operation. - /// - /// The ETag of the entity. - public string ETag { get; set; } - - public ShapeEntity Shape { get; set; } - - public virtual void ReadEntity(IDictionary properties, OperationContext operationContext) - { - TableEntity.ReadUserObject(this.Shape, properties, operationContext); - } - - public virtual IDictionary WriteEntity(OperationContext operationContext) - { - return TableEntity.WriteUserObject(this.Shape, operationContext); - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ShapeEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ShapeEntity.cs deleted file mode 100644 index 8fa6829d48cc4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/Table/Entities/ShapeEntity.cs +++ /dev/null @@ -1,46 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright 2012 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. -// -//----------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - public class ShapeEntity - { - public ShapeEntity() - { - } - - public ShapeEntity(string partitionKey, string rowKey, string name, int length, int breadth) - { - this.PartitionKey = partitionKey; - this.RowKey = rowKey; - this.Name = name; - this.Length = length; - this.Breadth = breadth; - } - - public string PartitionKey; - public string RowKey; - public string Name { get; set; } - public int Length { get; set; } - public int Breadth { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestBase.Common.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestBase.Common.cs deleted file mode 100644 index f04662db5ba14..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestBase.Common.cs +++ /dev/null @@ -1,108 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Blob; -using Microsoft.WindowsAzure.Storage.Queue; -using Microsoft.WindowsAzure.Storage.Table; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; - -#if WINDOWS_DESKTOP -using System.ServiceModel.Channels; -#endif - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestBase - { - private const AuthenticationScheme DefaultAuthenticationScheme = AuthenticationScheme.SharedKey; - - public static byte[] GetRandomBuffer(int size) - { - byte[] buffer = new byte[size]; - Random random = new Random(); - random.NextBytes(buffer); - return buffer; - } - -#if WINDOWS_DESKTOP - public static WCFBufferManagerAdapter BlobBufferManager = new WCFBufferManagerAdapter(BufferManager.CreateBufferManager(512 * (int)Constants.MB, 64 * (int)Constants.KB), 64 * (int)Constants.KB); - - public static WCFBufferManagerAdapter TableBufferManager = new WCFBufferManagerAdapter(BufferManager.CreateBufferManager(256 * (int)Constants.MB, 64 * (int)Constants.KB), 64 * (int)Constants.KB); - - public static WCFBufferManagerAdapter QueueBufferManager = new WCFBufferManagerAdapter(BufferManager.CreateBufferManager(64 * (int)Constants.MB, (int)Constants.KB), (int)Constants.KB); -#else - public static MockBufferManager BlobBufferManager = new MockBufferManager(64 * (int)Constants.KB); - - public static MockBufferManager TableBufferManager = new MockBufferManager(64 * (int)Constants.KB); - - public static MockBufferManager QueueBufferManager = new MockBufferManager((int)Constants.KB); - -#endif - - public static CloudTableClient GenerateCloudTableClient() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - CloudTableClient client = new CloudTableClient(baseAddressUri, TestBase.StorageCredentials); - client.AuthenticationScheme = DefaultAuthenticationScheme; - -#if WINDOWS_DESKTOP - client.BufferManager = BlobBufferManager; -#endif - - return client; - } - - public static CloudBlobClient GenerateCloudBlobClient() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - client.AuthenticationScheme = DefaultAuthenticationScheme; - -#if WINDOWS_DESKTOP - client.BufferManager = TableBufferManager; -#endif - - return client; - } - - public static CloudQueueClient GenerateCloudQueueClient() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint); - CloudQueueClient client = new CloudQueueClient(baseAddressUri, TestBase.StorageCredentials); - client.AuthenticationScheme = DefaultAuthenticationScheme; - -#if WINDOWS_DESKTOP - client.BufferManager = QueueBufferManager; -#endif - - return client; - } - - public static TestConfigurations TestConfigurations { get; private set; } - - public static TenantConfiguration TargetTenantConfig { get; private set; } - - public static TenantType CurrentTenantType { get; private set; } - - /// - /// The StorageCredentials created from account settings in the target tenant config. - /// - public static StorageCredentials StorageCredentials { get; private set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestCategoryConstants.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestCategoryConstants.cs deleted file mode 100644 index 684d1c704a6bf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestCategoryConstants.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - public static class ComponentCategory - { - public const string Auth = "Auth"; - - public const string Core = "Core"; - - public const string RetryPolicies = "RetryPolicies"; - - public const string Blob = "Blob"; - - public const string Queue = "Queue"; - - public const string Table = "Table"; - } - - public static class TestTypeCategory - { - public const string UnitTest = "UnitTest"; - - public const string FuntionalTest = "FuntionalTest"; - - public const string StressTest = "StressTest"; - } - - public static class SmokeTestCategory - { - public const string Smoke = "Smoke"; - - public const string NonSmoke = "NonSmoke"; - } - - public static class TenantTypeCategory - { - public const string DevStore = "DevStore"; - - public const string DevFabric = "DevFabric"; - - public const string Cloud = "Cloud"; - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantConfiguration.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantConfiguration.cs deleted file mode 100644 index bd80d53a97b7e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - public class TenantConfiguration - { - public string TenantName { get; internal set; } - public string AccountName { get; internal set; } - public string AccountKey { get; internal set; } - public string BlobServiceEndpoint { get; internal set; } - public string QueueServiceEndpoint { get; internal set; } - public string TableServiceEndpoint { get; internal set; } - public TenantType TenantType { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantType.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantType.cs deleted file mode 100644 index a966ad580e06d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TenantType.cs +++ /dev/null @@ -1,31 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; - -namespace Microsoft.WindowsAzure.Storage -{ - [Flags] - public enum TenantType - { - None = 0x0, - DevStore = 0x1, - DevFabric = 0x2, - Cloud = 0x4, - All = 0x7 - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TestConfigurations.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TestConfigurations.cs deleted file mode 100644 index 85dfcebcedd8a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigProcess/TestConfigurations.cs +++ /dev/null @@ -1,59 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Xml.Linq; - -namespace Microsoft.WindowsAzure.Storage -{ - public class TestConfigurations - { - public static readonly string DefaultTestConfigFilePath = @"TestConfigurations.xml"; - public string TargetTenantName { get; internal set; } - public List TenantConfigurations { get; internal set; } - - public static TestConfigurations ReadFromXml(XDocument testConfigurationsDoc) - { - XElement testConfigurationsElement = testConfigurationsDoc.Element("TestConfigurations"); - return ReadFromXml(testConfigurationsElement); - } - - public static TestConfigurations ReadFromXml(XElement testConfigurationsElement) - { - TestConfigurations result = new TestConfigurations(); - - result.TargetTenantName = (string)testConfigurationsElement.Element("TargetTestTenant"); - - result.TenantConfigurations = new List(); - foreach (XElement tenantConfigurationElement in testConfigurationsElement.Element("TenantConfigurations").Elements("TenantConfiguration")) - { - TenantConfiguration config = new TenantConfiguration(); - config.TenantName = (string)tenantConfigurationElement.Element("TenantName"); - config.AccountName = (string)tenantConfigurationElement.Element("AccountName"); - config.AccountKey = (string)tenantConfigurationElement.Element("AccountKey"); - config.BlobServiceEndpoint = (string)tenantConfigurationElement.Element("BlobServiceEndpoint"); - config.QueueServiceEndpoint = (string)tenantConfigurationElement.Element("QueueServiceEndpoint"); - config.TableServiceEndpoint = (string)tenantConfigurationElement.Element("TableServiceEndpoint"); - config.TenantType = (TenantType)Enum.Parse(typeof(TenantType), (string)tenantConfigurationElement.Element("TenantType"), true); - result.TenantConfigurations.Add(config); - } - - return result; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigurations.xml b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigurations.xml deleted file mode 100644 index 09b1f74fe47f0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestConfigurations.xml +++ /dev/null @@ -1,23 +0,0 @@ - -ProductionTenant - - - DevStore - DevStore - devstoreaccount1 - Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== - http://127.0.0.1:10000/devstoreaccount1 - http://127.0.0.1:10001/devstoreaccount1 - http://127.0.0.1:10002/devstoreaccount1 - - - ProductionTenant - Cloud - [ACCOUNT NAME HERE] - [ACCOUNT KEY HERE] - http://[ACCOUNT].blob.core.windows.net - http://[ACCOUNT].queue.core.windows.net - http://[ACCOUNT].table.core.windows.net - - - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestHelper.Common.cs b/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestHelper.Common.cs deleted file mode 100644 index 558370f05aa28..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/Common/TestHelper.Common.cs +++ /dev/null @@ -1,311 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Blob; -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestHelper - { - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static T ExpectedException(Action operation, string operationDescription) - where T : Exception - { - try - { - operation(); - } - catch (T e) - { - return e; - } - catch (Exception ex) - { - T e = ex as T; // Test framework changes the value under debugger - if (e != null) - { - return e; - } - Assert.Fail("Invalid exception {0} for operation: {1}", ex.GetType(), operationDescription); - } - - Assert.Fail("No exception received while while expecting {0}: {1}", typeof(T).ToString(), operationDescription); - return null; - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static void ExpectedException(Action operation, string operationDescription, int expectedStatusCode) - { - OperationContext opContext = new OperationContext(); - try - { - operation(opContext); - } - catch (Exception) - { - Assert.AreEqual(expectedStatusCode, opContext.LastResult.HttpStatusCode, "Http status code is unexpected."); - return; - } - - Assert.Fail("No exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } - - - internal static void AssertNAttempts(OperationContext ctx, int n) - { - Assert.AreEqual(n, ctx.RequestResults.Count(), String.Format("Operation took more than {0} attempt(s) to complete", n)); - } - -#if TASK - internal static void AssertCancellation(OperationContext ctx) - { - TestHelper.AssertNAttempts(ctx, 1); - Assert.IsInstanceOfType(ctx.LastResult.Exception, typeof(StorageException)); - Assert.AreEqual("Operation was canceled by user.", ctx.LastResult.Exception.Message); - Assert.AreEqual((int)HttpStatusCode.Unused, ((StorageException)ctx.LastResult.Exception).RequestInformation.HttpStatusCode); - Assert.AreEqual("Unused", ((StorageException)ctx.LastResult.Exception).RequestInformation.HttpStatusMessage); - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static T ExpectedExceptionTask(Task operation, string operationDescription) - where T : Exception - { - try - { - operation.Wait(); - } - catch (AggregateException ex) - { - ex = ex.Flatten(); - if (ex.InnerExceptions.Count > 1) - { - Assert.Fail("Multiple exceptions {0} for operation: {1}", ex.GetType(), operationDescription); - } - - T e = ex.InnerException as T; // Test framework changes the value under debugger - if (e != null) - { - Assert.IsTrue(operation.IsCompleted); - if (ex.InnerException is OperationCanceledException) - { - Assert.IsTrue(operation.IsCanceled); - Assert.IsFalse(operation.IsFaulted); - Assert.AreEqual(TaskStatus.Canceled, operation.Status); - } - else - { - Assert.IsFalse(operation.IsCanceled); - Assert.IsTrue(operation.IsFaulted); - Assert.AreEqual(TaskStatus.Faulted, operation.Status); - } - - return e; - } - Assert.Fail("Invalid exception {0} for operation: {1}", ex.GetType(), operationDescription); - } - catch (Exception ex) - { - Assert.Fail("Invalid exception {0} for operation: {1}", ex.GetType(), operationDescription); - } - - Assert.Fail("No exception received while while expecting {0}: {1}", typeof(T).ToString(), operationDescription); - return null; - } -#endif - - /// - /// Compares two streams. - /// - internal static void AssertStreamsAreEqual(Stream src, Stream dst) - { - Assert.AreEqual(src.Length, dst.Length); - - long origDstPosition = dst.Position; - long origSrcPosition = src.Position; - - dst.Position = 0; - src.Position = 0; - - for (int i = 0; i < src.Length; i++) - { - Assert.AreEqual(src.ReadByte(), dst.ReadByte()); - } - - dst.Position = origDstPosition; - src.Position = origSrcPosition; - } - - /// - /// Compares two streams from the starting positions and up to length bytes. - /// - internal static void AssertStreamsAreEqualAtIndex(MemoryStream src, MemoryStream dst, int srcIndex, int dstIndex, int length) - { - byte[] origBuffer = src.ToArray(); - byte[] retrBuffer = dst.ToArray(); - - for (int i = 0; i < length; i++) - { - Assert.AreEqual(origBuffer[srcIndex + i], retrBuffer[dstIndex + i]); - } - } - - /// - /// Compares two byte buffers. - /// - internal static void AssertBuffersAreEqual(byte[] src, byte[] dst) - { - Assert.AreEqual(src.Length, dst.Length); - - for (int i = 0; i < src.Length; i++) - { - Assert.AreEqual(src[i], dst[i]); - } - } - - /// - /// Validates if this test supports the currnet target tenant. - /// Skips the current test if the target tenant is not supported. - /// - public static void ValidateIfTestSupportTargetTenant(TenantType supportedTenantTypes) - { - if ((supportedTenantTypes & TestBase.CurrentTenantType) == 0) - { - Assert.Inconclusive("This test is skipped because the target test tenant is {0}.", TestBase.CurrentTenantType); - } - } - - /// - /// Remove the local fiddler proxy from a URI. - /// - /// The URI to change. - /// The URI without the local fiddler proxy. - internal static Uri Defiddler(Uri uri) - { - string fiddlerString = "ipv4.fiddler"; - string replacementString = "127.0.0.1"; - - string uriString = uri.AbsoluteUri; - if (uriString.Contains(fiddlerString)) - { - return new Uri(uriString.Replace(fiddlerString, replacementString)); - } - else - { - return uri; - } - } - - /// - /// Remove the local fiddler proxy from a blob reference. - /// - /// The blob to change. - /// A blob reference without the local fiddler proxy. - /// If no fiddler proxy is present, the old blob reference is returned. - internal static CloudBlockBlob Defiddler(CloudBlockBlob blob) - { - Uri oldUri = blob.Uri; - Uri newUri = Defiddler(oldUri); - - if (newUri != oldUri) - { - return new CloudBlockBlob(newUri, blob.SnapshotTime, blob.ServiceClient.Credentials); - } - else - { - return blob; - } - } - - /// - /// Remove the local fiddler proxy from a blob reference. - /// - /// The blob to change. - /// A blob reference without the local fiddler proxy. - /// If no fiddler proxy is present, the old blob reference is returned. - internal static CloudPageBlob Defiddler(CloudPageBlob blob) - { - Uri oldUri = blob.Uri; - Uri newUri = Defiddler(oldUri); - - if (newUri != oldUri) - { - return new CloudPageBlob(newUri, blob.SnapshotTime, blob.ServiceClient.Credentials); - } - else - { - return blob; - } - } - - internal static void ValidateResponse(OperationContext opContext, int expectedAttempts, int expectedStatusCode, string[] allowedErrorCodes, string errorMessageBeginsWith) - { - ValidateResponse(opContext, expectedAttempts, expectedStatusCode, allowedErrorCodes, new string[] { errorMessageBeginsWith }); - } - - internal static void ValidateResponse(OperationContext opContext, int expectedAttempts, int expectedStatusCode, string[] allowedErrorCodes, string[] errorMessageBeginsWith) - { - ValidateResponse(opContext, expectedAttempts, expectedStatusCode, allowedErrorCodes, errorMessageBeginsWith, true); - } - - internal static void ValidateResponse(OperationContext opContext, int expectedAttempts, int expectedStatusCode, string[] allowedErrorCodes, string[] errorMessageBeginsWith, bool stripIndex) - { - TestHelper.AssertNAttempts(opContext, 1); - Assert.AreEqual(opContext.LastResult.HttpStatusCode, expectedStatusCode); - Assert.IsTrue(allowedErrorCodes.Contains(opContext.LastResult.ExtendedErrorInformation.ErrorCode), "Unexpected Error Code, recieved" + opContext.LastResult.ExtendedErrorInformation.ErrorCode); - - if (errorMessageBeginsWith != null) - { - Assert.IsNotNull(opContext.LastResult.ExtendedErrorInformation.ErrorMessage); - string message = opContext.LastResult.ExtendedErrorInformation.ErrorMessage; - if (stripIndex) - { - int semDex = opContext.LastResult.ExtendedErrorInformation.ErrorMessage.IndexOf(":"); - semDex = semDex > 2 ? -1 : semDex; - message = message.Substring(semDex + 1); - } - - Assert.IsTrue(errorMessageBeginsWith.Where((s) => message.StartsWith(s)).Count() > 0, opContext.LastResult.ExtendedErrorInformation.ErrorMessage); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/App.config b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/App.config deleted file mode 100644 index a41fc9dad3b22..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/App.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.csproj b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.csproj deleted file mode 100644 index 0928689bf9dd9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.csproj +++ /dev/null @@ -1,160 +0,0 @@ - - - - Debug - AnyCPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B} - Library - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.Storage.Test - v4.0 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - UnitTest - - - - true - full - false - bin\Debug\ - TRACE;DEBUG;WINDOWS_DESKTOP;TASK - prompt - 4 - 1685 - - - true - MSSharedLibKey.snk - true - pdbonly - true - bin\Release\ - TRACE;WINDOWS_DESKTOP;TASK - prompt - 4 - 1685 - - - - ..\FaultInjection\Dependencies\DotNet2\FiddlerCore.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Blob\Blob - - - Core\Core - - - Queue\Queue - - - Table\Table - - - Table\Entities\Table - - - TestConfigProcess\TestConfigProcess - - - - - - Blob\Blob - - - Core\Core - - - Properties\Properties - - - Blob\Protocol\Protocol - - - Queue\Queue - - - Table\Table - - - Table\Entities\Entities - - - Table\SAS\SAS - - - - - - - - - - - {c6787633-b26a-4913-a762-4c0ffceb6fe3} - DotNet40 %28Lib\DotNet40%29 - - - {ca607e8f-2906-4065-a1a9-4a3733f0cc31} - HttpMangler - - - {6eb781c5-6d91-48f0-8f79-ec1e4edaaf7b} - XStoreMangler - - - - - Readme.txt - - - TestConfigurations.xml - Always - Designer - - - - - Designer - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.sln b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.sln deleted file mode 100644 index 2dccf4ccd65fa..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/DotNet40.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet40", "DotNet40.csproj", "{1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1E1FF9EF-05E0-4305-AFD1-AD0A20069B8B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Properties/AssemblyInfo.cs deleted file mode 100644 index fa1e9b55c9208..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.Storage.Test.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ebfe856a-e09c-47f3-a993-601b760dc25b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/CancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/CancellationUnitTests.cs deleted file mode 100644 index 437d3336b34f6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/CancellationUnitTests.cs +++ /dev/null @@ -1,231 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class CancellationUnitTests : TableTestBase - { - #region Locals + Ctors - public CancellationUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Table Operation - - [TestMethod] - [Description("TableOperation Cancellation Batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", "foo"); - - for (int m = 0; m < 20; m++) - { - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[50 * 1024])); - } - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => currentTable.BeginExecute(TableOperation.Insert(insertEntity), (TableRequestOptions)options, opContext, callback, state), - (res) => currentTable.EndExecute(res)); - } - - #endregion - - #region Batch Operation - - [TestMethod] - [Description("TableBatchOperation Cancellation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchOperationCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", m.ToString()); - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[30 * 1024])); - batch.Insert(insertEntity); - } - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => currentTable.BeginExecuteBatch(batch, (TableRequestOptions)options, opContext, callback, state), - (res) => currentTable.EndExecuteBatch(res)); - } - - #endregion - - #region TableQuery - - [TestMethod] - [Description("Test Table Query Cancellation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableTestTableQueryCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", m.ToString()); - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[30 * 1024])); - batch.Insert(insertEntity); - } - - currentTable.ExecuteBatch(batch); - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "insert test")); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => currentTable.BeginExecuteQuerySegmented(query, null, (TableRequestOptions)options, opContext, callback, state), - (res) => currentTable.EndExecuteQuerySegmented(res)); - } - - #endregion - - #region ACLS - - [TestMethod] - [Description("Test Set Table ACL Cancellation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetACLCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - CloudTable tbl = tableClient.GetTableReference(GenerateRandomTableName()); - - TablePermissions perms = new TablePermissions(); - // Add a policy, check setting and getting. - perms.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => tbl.BeginSetPermissions(perms, (TableRequestOptions)options, opContext, callback, state), - tbl.EndSetPermissions); - } - - [TestMethod] - [Description("Test Get Table ACL Cancellation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetACLCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - CloudTable tbl = tableClient.GetTableReference(GenerateRandomTableName()); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => tbl.BeginGetPermissions((TableRequestOptions)options, opContext, callback, state), - (res) => tbl.EndGetPermissions(res)); - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/CancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/CancellationUnitTests.cs deleted file mode 100644 index 4ef0a533b1db0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/CancellationUnitTests.cs +++ /dev/null @@ -1,167 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System.Data.Services.Client; -using System.Linq; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - [TestClass] - public class CancellationUnitTests : TableTestBase - { - #region Locals + Ctors - public CancellationUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - } - - #endregion - - #region Save Changes - - [TestMethod] - [Description("Test Table SaveChanges CancellationNonBatch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableTestSaveChangesCancellationNonBatch() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - } - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, (TableRequestOptions)options, opContext, callback, state), - (res) => ctx.EndSaveChangesWithRetries(res)); - } - - [TestMethod] - [Description("Test Table SaveChanges Cancellation Batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableTestSaveChangesCancellationBatch() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - } - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => ctx.BeginSaveChangesWithRetries(SaveChangesOptions.Batch, (TableRequestOptions)options, opContext, callback, state), - (res) => ctx.EndSaveChangesWithRetries(res)); - } - #endregion - - [TestMethod] - [Description("Test Table Query Cancellation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableTestSegmentedQueryCancellation() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - } - ctx.SaveChangesWithRetries(); - - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => query.BeginExecuteSegmented(null, (TableRequestOptions)options, opContext, callback, state), - (res) => query.EndExecuteSegmented(res)); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/BaseEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/BaseEntity.cs deleted file mode 100644 index 812eec0f99134..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/BaseEntity.cs +++ /dev/null @@ -1,45 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.Entities -{ - public class BaseEntity : TableServiceEntity - { - public BaseEntity() - : base() - { - } - - public BaseEntity(string pk, string rk) - : base(pk, rk) - { - } - - public string A { get; set; } - public string B { get; set; } - public string C { get; set; } - - public void Randomize() - { - A = Guid.NewGuid().ToString(); - B = Guid.NewGuid().ToString(); - C = Guid.NewGuid().ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/ComplexEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/ComplexEntity.cs deleted file mode 100644 index 08264b2e2d5bd..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/ComplexEntity.cs +++ /dev/null @@ -1,146 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.Entities -{ - public class ComplexEntity : TableServiceEntity - { - public ComplexEntity() - : base() - { - } - - public ComplexEntity(string pk, string rk) - : base(pk, rk) - { - } - - private DateTime dateTime = DateTime.Now; - public DateTime DateTime - { - get { return dateTime; } - set { dateTime = value; } - } - - private Boolean boolObj = false; - public Boolean Bool - { - get { return boolObj; } - set { boolObj = value; } - } - - private bool boolPrimitive = false; - public bool BoolPrimitive - { - get { return boolPrimitive; } - set { boolPrimitive = value; } - } - - private Byte[] binary = new Byte[] { 1, 2, 3, 4 }; - public Byte[] Binary - { - get { return binary; } - set { binary = value; } - } - - private byte[] binaryPrimitive = new byte[] { 1, 2, 3, 4 }; - public byte[] BinaryPrimitive - { - get { return binaryPrimitive; } - set { binaryPrimitive = value; } - } - - private double doublePrimitive = (double)1234.1234; - public double DoublePrimitive - { - get { return doublePrimitive; } - set { doublePrimitive = value; } - } - - private Double doubleOBj = (Double)1234.1234; - public Double Double - { - get { return doubleOBj; } - set { doubleOBj = value; } - } - - private Guid guid = Guid.NewGuid(); - public Guid Guid - { - get { return guid; } - set { guid = value; } - } - - private int integerPrimitive = 1234; - public int IntegerPrimitive - { - get { return integerPrimitive; } - set { integerPrimitive = value; } - } - - private Int32 int32 = 1234; - public Int32 Int32 - { - get { return int32; } - set { int32 = value; } - } - - private long longPrimitive = 123456789012; - public long LongPrimitive - { - get { return longPrimitive; } - set { longPrimitive = value; } - } - - private Int64 int64 = 123456789012; - public Int64 Int64 - { - get { return int64; } - set { int64 = value; } - } - - private string stringObj = "test"; - public string String - { - get { return stringObj; } - set { stringObj = value; } - } - - public static void AssertEquality(ComplexEntity a, ComplexEntity b) - { - Assert.AreEqual(a.String, b.String); - Assert.AreEqual(a.Int64, b.Int64); - Assert.AreEqual(a.LongPrimitive, b.LongPrimitive); - Assert.AreEqual(a.Int32, b.Int32); - Assert.AreEqual(a.IntegerPrimitive, b.IntegerPrimitive); - Assert.AreEqual(a.Guid, b.Guid); - Assert.AreEqual(a.Double, b.Double); - Assert.AreEqual(a.DoublePrimitive, b.DoublePrimitive); - Assert.AreEqual(a.BinaryPrimitive, b.BinaryPrimitive); - Assert.AreEqual(a.Binary, b.Binary); - Assert.AreEqual(a.BoolPrimitive, b.BoolPrimitive); - Assert.AreEqual(a.Bool, b.Bool); - Assert.AreEqual(a.DateTime, b.DateTime); - - Assert.AreEqual(a.PartitionKey, b.PartitionKey); - Assert.AreEqual(a.RowKey, b.RowKey); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/MergeEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/MergeEntity.cs deleted file mode 100644 index 34807a7f8f784..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/MergeEntity.cs +++ /dev/null @@ -1,45 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.Entities -{ - public class MergeEntity : TableServiceEntity - { - public MergeEntity() - : base() - { - } - - public MergeEntity(string pk, string rk) - : base(pk, rk) - { - } - - public string D { get; set; } - public string E { get; set; } - public string F { get; set; } - - public void Randomize() - { - D = Guid.NewGuid().ToString(); - E = Guid.NewGuid().ToString(); - F = Guid.NewGuid().ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/UnionEnitity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/UnionEnitity.cs deleted file mode 100644 index c77b37debda26..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/Entities/UnionEnitity.cs +++ /dev/null @@ -1,51 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.Entities -{ - class UnionEnitity : TableServiceEntity - { - public UnionEnitity() - : base() - { - } - - public UnionEnitity(string pk, string rk) - : base(pk, rk) - { - } - - public string A { get; set; } - public string B { get; set; } - public string C { get; set; } - public string D { get; set; } - public string E { get; set; } - public string F { get; set; } - - public void Randomize() - { - A = Guid.NewGuid().ToString(); - B = Guid.NewGuid().ToString(); - C = Guid.NewGuid().ToString(); - D = Guid.NewGuid().ToString(); - E = Guid.NewGuid().ToString(); - F = Guid.NewGuid().ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasFunctionalTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasFunctionalTests.cs deleted file mode 100644 index 53b0451c942d6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasFunctionalTests.cs +++ /dev/null @@ -1,208 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.SAS -{ - [TestClass] - public class TableSasFunctionalTests : TableTestBase - { - #region Locals + Ctors - public TableSasFunctionalTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - // [TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - // [TestCleanup()] - // public void MyTestCleanup() { } - - #endregion - - #region Permissions - - [TestMethod] - [Description("Tests setting and getting table permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetPermissionTest() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions; - TablePermissions testPermissions; - - // Test new table permissions. - expectedPermissions = new TablePermissions(); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Test setting empty permissions. - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a null policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.None, - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromDays(0.5), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Update, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(6), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(6.5) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasUnitTests.cs deleted file mode 100644 index c811660fb1f6a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/SAS/TableSasUnitTests.cs +++ /dev/null @@ -1,1504 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices.SAS -{ - [TestClass] - public class TableSasUnitTests : TableTestBase - { - #region Locals + Ctors - public TableSasUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - // - // Use TestInitialize to run code before running each test - // [TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - // [TestCleanup()] - // public void MyTestCleanup() { } - - #endregion - - #region Constructor Tests - - [TestMethod] - [Description("Test TableSas via various constructors")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSASConstructors() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - // Prepare SAS authentication with full permissions - string sasToken = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null /* accessPolicyIdentifier */, - null /* startPk */, - null /* startRk */, - null /* endPk */, - null /* endRk */); - - CloudStorageAccount sasAccount; - StorageCredentials sasCreds; - CloudTableClient sasClient; - CloudTable sasTable; - TableServiceContext sasContext; - Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - int count; - - // SAS via connection string parse - sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken)); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - sasContext = sasClient.GetTableServiceContext(); - count = sasContext.CreateQuery(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); - Assert.AreEqual(1, count); - - // SAS via account constructor - sasCreds = new StorageCredentials(sasToken); - sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - sasContext = sasClient.GetTableServiceContext(); - count = sasContext.CreateQuery(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); - Assert.AreEqual(1, count); - - // SAS via client constructor URI + Creds - sasCreds = new StorageCredentials(sasToken); - sasClient = new CloudTableClient(baseUri, sasCreds); - sasContext = sasClient.GetTableServiceContext(); - count = sasContext.CreateQuery(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count(); - Assert.AreEqual(1, count); - - } - finally - { - table.DeleteIfExists(); - } - } - - #endregion - - #region Permissions - - [TestMethod] - [Description("Tests setting and getting table permissions Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetGetPermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests setting and getting table permissions overload")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetGetPermissionsOverloadSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - KeyValuePair policy = new KeyValuePair(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(policy); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests clearing table permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableContainsAndClearPermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - string key = Guid.NewGuid().ToString(); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(policy); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - Assert.AreEqual(true, expectedPermissions.SharedAccessPolicies.Contains(policy)); - Assert.AreEqual(true, expectedPermissions.SharedAccessPolicies.ContainsKey(key)); - - expectedPermissions.SharedAccessPolicies.Clear(); - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - Assert.AreEqual(0, expectedPermissions.SharedAccessPolicies.Count); - AssertPermissionsEqual(new TablePermissions(), testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests copying table permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableCopyPermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - TablePermissions expectedPermissions = new TablePermissions(); - - string key = Guid.NewGuid().ToString(); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - string key2 = Guid.NewGuid().ToString(); - KeyValuePair policy2 = new KeyValuePair(key2, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - expectedPermissions.SharedAccessPolicies.Add(policy); - expectedPermissions.SharedAccessPolicies.Add(policy2); - - KeyValuePair[] sharedAccessPolicyArray = new KeyValuePair[2]; - expectedPermissions.SharedAccessPolicies.CopyTo(sharedAccessPolicyArray, 0); - Assert.AreEqual(2, sharedAccessPolicyArray.Length); - Assert.AreEqual(policy, sharedAccessPolicyArray[0]); - Assert.AreEqual(policy2, sharedAccessPolicyArray[1]); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests removing table permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRemovePermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - string key = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry - }); - - string key2 = Guid.NewGuid().ToString(); - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair policy2 = new KeyValuePair(key2, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2 - }); - - expectedPermissions.SharedAccessPolicies.Add(policy); - expectedPermissions.SharedAccessPolicies.Add(policy2); - - Assert.AreEqual(2, expectedPermissions.SharedAccessPolicies.Count); - expectedPermissions.SharedAccessPolicies.Remove(policy2); - table.SetPermissions(expectedPermissions); - Thread.Sleep(3 * 1000); - testPermissions = table.GetPermissions(); - - Assert.AreEqual(1, testPermissions.SharedAccessPolicies.Count); - Assert.AreEqual(policy.Key, testPermissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(policy.Value.Permissions, testPermissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(policy.Value.SharedAccessStartTime, testPermissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(policy.Value.SharedAccessExpiryTime, testPermissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - - expectedPermissions.SharedAccessPolicies.Add(policy2); - table.SetPermissions(expectedPermissions); - Thread.Sleep(3 * 1000); - testPermissions = table.GetPermissions(); - Assert.AreEqual(2, testPermissions.SharedAccessPolicies.Count); - - expectedPermissions.SharedAccessPolicies.Remove(key2); - table.SetPermissions(expectedPermissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(1, expectedPermissions.SharedAccessPolicies.Count); - testPermissions = table.GetPermissions(); - Assert.AreEqual(1, testPermissions.SharedAccessPolicies.Count); - Assert.AreEqual(policy.Key, testPermissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(policy.Value.Permissions, testPermissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(policy.Value.SharedAccessStartTime, testPermissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(policy.Value.SharedAccessExpiryTime, testPermissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests TryGetValue for permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableTryGetValuePermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - string key = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry - }); - - string key2 = Guid.NewGuid().ToString(); - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair policy2 = new KeyValuePair(key2, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2 - }); - - expectedPermissions.SharedAccessPolicies.Add(policy); - expectedPermissions.SharedAccessPolicies.Add(policy2); - Assert.AreEqual(2, expectedPermissions.SharedAccessPolicies.Count); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(3 * 1000); - testPermissions = table.GetPermissions(); - - SharedAccessTablePolicy retrPolicy; - testPermissions.SharedAccessPolicies.TryGetValue(key, out retrPolicy); - Assert.AreEqual(policy.Value.Permissions, retrPolicy.Permissions); - Assert.AreEqual(policy.Value.SharedAccessStartTime, retrPolicy.SharedAccessStartTime); - Assert.AreEqual(policy.Value.SharedAccessExpiryTime, retrPolicy.SharedAccessExpiryTime); - - SharedAccessTablePolicy retrPolicy2; - testPermissions.SharedAccessPolicies.TryGetValue(key2, out retrPolicy2); - Assert.AreEqual(policy2.Value.Permissions, retrPolicy2.Permissions); - Assert.AreEqual(policy2.Value.SharedAccessStartTime, retrPolicy2.SharedAccessStartTime); - Assert.AreEqual(policy2.Value.SharedAccessExpiryTime, retrPolicy2.SharedAccessExpiryTime); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests Getter for Values for permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetValuesPermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - string key = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry - }); - - string key2 = Guid.NewGuid().ToString(); - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair policy2 = new KeyValuePair(key2, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2 - }); - - expectedPermissions.SharedAccessPolicies.Add(policy); - expectedPermissions.SharedAccessPolicies.Add(policy2); - Assert.AreEqual(2, expectedPermissions.SharedAccessPolicies.Count); - - ICollection values = expectedPermissions.SharedAccessPolicies.Values; - Assert.AreEqual(2, values.Count); - Assert.AreEqual(policy.Value, values.ElementAt(0)); - Assert.AreEqual(policy2.Value, values.ElementAt(1)); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests GetEnumerator for permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetEnumeratorPermissionsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - string key = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - KeyValuePair policy = new KeyValuePair(key, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry - }); - - string key2 = Guid.NewGuid().ToString(); - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair policy2 = new KeyValuePair(key2, new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2 - }); - - expectedPermissions.SharedAccessPolicies.Add(policy); - expectedPermissions.SharedAccessPolicies.Add(policy2); - Assert.AreEqual(2, expectedPermissions.SharedAccessPolicies.Count); - - IEnumerator> policies = expectedPermissions.SharedAccessPolicies.GetEnumerator(); - policies.MoveNext(); - Assert.AreEqual(policy, policies.Current); - policies.MoveNext(); - Assert.AreEqual(policy2, policies.Current); - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Tests setting and getting table permissions APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetGetPermissionsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetries(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - table.BeginSetPermissions(expectedPermissions, (res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - table.EndSetPermissions(result); - } - - Thread.Sleep(30 * 1000); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - table.BeginGetPermissions((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - testPermissions = table.EndGetPermissions(result); - } - - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Tests setting and getting table permissions Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetGetPermissionsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.CreateAsync().Wait(); - - TableServiceContext context = tableClient.GetTableServiceContext(); - context.AddObject(table.Name, new BaseEntity("PK", "RK")); - context.SaveChangesWithRetriesAsync().Wait(); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissionsAsync().Result; - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissionsAsync(expectedPermissions).Wait(); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissionsAsync(null, new OperationContext()).Result; - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } -#endif - #endregion - - #region SAS Operations - - [TestMethod] - [Description("Tests table SAS with query permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasQueryTest() - { - TestTableSas(SharedAccessTablePermissions.Query); - } - - [TestMethod] - [Description("Tests table SAS with delete permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasDeleteTest() - { - TestTableSas(SharedAccessTablePermissions.Delete); - } - - [TestMethod] - [Description("Tests table SAS with process and update permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasUpdateTest() - { - TestTableSas(SharedAccessTablePermissions.Update); - } - - [TestMethod] - [Description("Tests table SAS with add permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasAddTest() - { - TestTableSas(SharedAccessTablePermissions.Add); - } - - [TestMethod] - [Description("Tests table SAS with full permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasFullTest() - { - TestTableSas(SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// Various table range constraints are tested. - /// - /// The permissions to test. - internal void TestTableSas(SharedAccessTablePermissions accessPermissions) - { - string startPk = "M"; - string startRk = "F"; - string endPk = "S"; - string endRk = "T"; - - // No ranges specified - TestTableSasWithRange(accessPermissions, null, null, null, null); - - // All ranges specified - TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, endRk); - - // StartPk & StartRK specified - TestTableSasWithRange(accessPermissions, startPk, startRk, null, null); - - // StartPk specified - TestTableSasWithRange(accessPermissions, startPk, null, null, null); - - // EndPk & EndRK specified - TestTableSasWithRange(accessPermissions, null, null, endPk, endRk); - - // EndPk specified - TestTableSasWithRange(accessPermissions, null, null, endPk, null); - - // StartPk and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, null, endPk, null); - - // StartRk and StartRK and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, null); - - // StartRk and EndPK and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, null, endPk, endRk); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// - /// The permissions to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - internal void TestTableSasWithRange( - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - TestContext.WriteLine("Testing SAS range: spk={0}; epk={1}; srk={2}; erk={3}", startPk, endPk, startRk, endRk); - - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - // Set up a policy - string identifier = Guid.NewGuid().ToString(); - TablePermissions permissions = new TablePermissions(); - permissions.SharedAccessPolicies.Add(identifier, new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddDays(1) - }); - table.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - // Prepare SAS authentication using access identifier - string sasString = table.GetSharedAccessSignature(new SharedAccessTablePolicy(), identifier, startPk, startRk, endPk, endRk); - CloudTableClient identifierSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Prepare SAS authentication using explicit policy - sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null, - startPk, - startRk, - endPk, - endRk); - - CloudTableClient explicitSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Point query - TestPointQuery(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestPointQuery(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Add row - TestAdd(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestAdd(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (merge) - TestUpdateMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpdateMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (replace) - TestUpdateReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpdateReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Delete row - TestDelete(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestDelete(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (merge) - TestUpsertMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpsertMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (replace) - TestUpsertReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpsertReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - } - finally - { - table.DeleteIfExists(); - } - } - - - /// - /// Test point queries entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestPointQuery( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action queryDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - TableServiceQuery query = (from entity in context.CreateQuery(tableName) - where entity.PartitionKey == tableEntity.PartitionKey && entity.RowKey == tableEntity.RowKey - select entity).AsTableServiceQuery(context); - IEnumerable list = query.Execute().ToList(); - Assert.AreEqual(1, list.Count()); - BaseEntity e = list.Single(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Query) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - queryDelegate, - "point query", - expectSuccess, - expectSuccess ? HttpStatusCode.OK : HttpStatusCode.NotFound); - } - - - /// - /// Test update (merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpdateMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - // Merge entity - tableEntity.A = "10"; - context.AttachTo(tableName, tableEntity, "*"); - context.UpdateObject(tableEntity); - context.SaveChangesWithRetries(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test update (replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpdateReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - // Replace entity - tableEntity.A = "20"; - context.AttachTo(tableName, tableEntity, "*"); - context.UpdateObject(tableEntity); - context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test adding entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestAdd( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - TableServiceContext referenceContext = testClient.GetTableServiceContext(); - - Action addDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - context.AddObject(tableName, tableEntity); - context.SaveChangesWithRetries(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Add) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - addDelegate, - "add", - expectSuccess, - expectSuccess ? HttpStatusCode.Created : HttpStatusCode.NotFound); - } - - /// - /// Test deleting entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestDelete( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - TableServiceContext referenceContext = testClient.GetTableServiceContext(); - - Action deleteDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - context.AttachTo(tableName, tableEntity, "*"); - context.DeleteObject(tableEntity); - context.SaveChangesWithRetries(); - context.Detach(tableEntity); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Delete) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - deleteDelegate, - "delete", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpsertMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - // Merge entity - tableEntity.A = "10"; - context.AttachTo(tableName, tableEntity); - context.UpdateObject(tableEntity); - context.SaveChangesWithRetries(); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpsertReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity) => - { - TableServiceContext context = testClient.GetTableServiceContext(); - - // Replace entity - tableEntity.A = "10"; - context.AttachTo(tableName, tableEntity); - context.UpdateObject(tableEntity); - context.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private void TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode) - { - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - runOperationDelegate, - opName, - expectSuccess, - expectedStatusCode, - false /* isRangeQuery */); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private void TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode, - bool isRangeQuery) - { - CloudTableClient referenceClient = GenerateCloudTableClient(); - TableServiceContext referenceContext = referenceClient.GetTableServiceContext(); - - string partitionKey = startPk ?? endPk ?? "M"; - string rowKey = startRk ?? endRk ?? "S"; - - // if we expect a success for creation - avoid inserting duplicate entities - BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey); - if (expectedStatusCode == HttpStatusCode.Created) - { - referenceContext.AttachTo(tableName, tableEntity, "*"); - referenceContext.DeleteObject(tableEntity); - try - { - referenceContext.SaveChangesWithRetries(); - } - catch (Exception) - { - } - } - else - { - // only for add we should not be adding the entity - referenceContext.AttachTo(tableName, tableEntity); - referenceContext.UpdateObject(tableEntity); - referenceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - } - - if (expectSuccess) - { - runOperationDelegate(tableEntity); - } - else - { - TestHelper.ExpectedException( - () => runOperationDelegate(tableEntity), - string.Format("{0} without appropriate permission.", opName), - HttpStatusCode.NotFound); - } - - if (startPk != null) - { - tableEntity.PartitionKey = "A"; - if (startPk.CompareTo(tableEntity.PartitionKey) <= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - () => runOperationDelegate(tableEntity), - string.Format("{0} before allowed partition key range", opName), - HttpStatusCode.NotFound); - tableEntity.PartitionKey = partitionKey; - } - - if (endPk != null) - { - tableEntity.PartitionKey = "Z"; - if (endPk.CompareTo(tableEntity.PartitionKey) >= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - () => runOperationDelegate(tableEntity), - string.Format("{0} after allowed partition key range", opName), - HttpStatusCode.NotFound); - - tableEntity.PartitionKey = partitionKey; - } - - if (startRk != null) - { - if (isRangeQuery || startPk != null) - { - tableEntity.PartitionKey = startPk; - tableEntity.RowKey = "A"; - if (startRk.CompareTo(tableEntity.RowKey) <= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - () => runOperationDelegate(tableEntity), - string.Format("{0} before allowed row key range", opName), - HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - - if (endRk != null) - { - if (isRangeQuery || endPk != null) - { - tableEntity.PartitionKey = endPk; - tableEntity.RowKey = "Z"; - if (endRk.CompareTo(tableEntity.RowKey) >= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - () => runOperationDelegate(tableEntity), - string.Format("{0} after allowed row key range", opName), - HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - } - #endregion - - #region SAS Error Conditions - - //[TestMethod] // Disabled until service bug is fixed - [Description("Attempt to use SAS to authenticate table operations that must not work with SAS.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasInvalidOperations() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - // Prepare SAS authentication with full permissions - string sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete, - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30) - }, - null, - null, - null, - null, - null); - - CloudTableClient sasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Construct a valid set of service properties to upload. - ServiceProperties properties = new ServiceProperties(); - properties.Logging.Version = "1.0"; - properties.Metrics.Version = "1.0"; - properties.Logging.RetentionDays = 9; - sasClient.GetServiceProperties(); - sasClient.SetServiceProperties(properties); - - // Test invalid client operations - // BUGBUG: ListTables hides the exception. We should fix this - // TestHelpers.ExpectedException(() => sasClient.ListTablesSegmented(), "List tables with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException(() => sasClient.GetServiceProperties(), "Get service properties with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException(() => sasClient.SetServiceProperties(properties), "Set service properties with SAS", HttpStatusCode.NotFound); - - CloudTable sasTable = sasClient.GetTableReference(table.Name); - - // Verify that creation fails with SAS - TestHelper.ExpectedException(() => sasTable.Create(), "Create a table with SAS", HttpStatusCode.NotFound); - - // Create the table. - table.Create(); - - // Test invalid table operations - TestHelper.ExpectedException(() => sasTable.Delete(), "Delete a table with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException(() => sasTable.GetPermissions(), "Get ACL with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException(() => sasTable.SetPermissions(new TablePermissions()), "Set ACL with SAS", HttpStatusCode.NotFound); - } - finally - { - table.DeleteIfExists(); - } - } - - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableEntityUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableEntityUnitTests.cs deleted file mode 100644 index 222b6b4af0edb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableEntityUnitTests.cs +++ /dev/null @@ -1,1001 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Linq; -using System.Net; -using System.Threading; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - [TestClass] - public class TableEntityUnitTests : TableTestBase - { - #region Locals + Ctors - public TableEntityUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - } - - #endregion - - #region Insert - - [TestMethod] - [Description("Single Entity Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsert() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetries(); - - // Retrieve Entity - ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == insertEntity.PartitionKey - && ent.RowKey == insertEntity.RowKey - select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - ComplexEntity.AssertEquality(insertEntity, retrievedEntity); - } - -#if TASK - [TestMethod] - [Description("Single Entity Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetriesAsync().Wait(); - - // Retrieve Entity - ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == insertEntity.PartitionKey - && ent.RowKey == insertEntity.RowKey - select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - ComplexEntity.AssertEquality(insertEntity, retrievedEntity); - } -#endif - - [TestMethod] - [Description("Single Entity Insert Conflict")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertConflict() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetries(); - - - // Attempt Insert Conflict Entity - TableServiceContext ctx2 = tableClient.GetTableServiceContext(); - ComplexEntity conflictEntity = new ComplexEntity("insert test", "foo"); - ctx2.AddObject(currentTable.Name, insertEntity); - OperationContext opContext = new OperationContext(); - - try - { - ctx2.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - - #endregion - - #region Insert Or Merge - - [TestMethod] - [Description("Single Entity Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertOrMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - - // Insert Or Merge with no pre-existing entity - MergeEntity insertOrMergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - insertOrMergeEntity.Randomize(); - ctx.AttachTo(currentTable.Name, insertOrMergeEntity, null); - ctx.UpdateObject(insertOrMergeEntity); - ctx.SaveChangesWithRetries(); - ctx.Detach(insertOrMergeEntity); - - // Retrieve Entity & Verify Contents - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.D, retrievedEntity.D); - Assert.AreEqual(insertOrMergeEntity.E, retrievedEntity.E); - Assert.AreEqual(insertOrMergeEntity.F, retrievedEntity.F); - - UnionEnitity mergedEntity = new UnionEnitity("insert test", "foo"); - mergedEntity.Randomize(); - mergedEntity.D = insertOrMergeEntity.D; - mergedEntity.E = insertOrMergeEntity.E; - mergedEntity.F = insertOrMergeEntity.F; - - ctx.AttachTo(currentTable.Name, mergedEntity, null); - ctx.UpdateObject(mergedEntity); - ctx.SaveChangesWithRetries(); - ctx.Detach(mergedEntity); - - // Retrieve Entity & Verify - retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergedEntity.A, retrievedEntity.A); - Assert.AreEqual(mergedEntity.B, retrievedEntity.B); - Assert.AreEqual(mergedEntity.C, retrievedEntity.C); - Assert.AreEqual(mergedEntity.D, retrievedEntity.D); - Assert.AreEqual(mergedEntity.E, retrievedEntity.E); - Assert.AreEqual(mergedEntity.F, retrievedEntity.F); - } - - #endregion - - #region Insert Or Replace - - [TestMethod] - [Description("Single Entity Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertOrReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - queryContext.MergeOption = MergeOption.NoTracking; - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - - // Insert Or Merge with no pre-existing entity - MergeEntity insertOrReplaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - insertOrReplaceEntity.Randomize(); - ctx.AttachTo(currentTable.Name, insertOrReplaceEntity, null); - ctx.UpdateObject(insertOrReplaceEntity); - ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - ctx.Detach(insertOrReplaceEntity); - - // Retrieve Entity & Verify Contents - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(null, retrievedEntity.A); - Assert.AreEqual(null, retrievedEntity.B); - Assert.AreEqual(null, retrievedEntity.C); - Assert.AreEqual(insertOrReplaceEntity.D, retrievedEntity.D); - Assert.AreEqual(insertOrReplaceEntity.E, retrievedEntity.E); - Assert.AreEqual(insertOrReplaceEntity.F, retrievedEntity.F); - - BaseEntity replacedEntity = new BaseEntity("insert test", "foo"); - replacedEntity.Randomize(); - - ctx.AttachTo(currentTable.Name, replacedEntity, null); - ctx.UpdateObject(replacedEntity); - ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - - // Retrieve Entity & Verify - retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replacedEntity.A, retrievedEntity.A); - Assert.AreEqual(replacedEntity.B, retrievedEntity.B); - Assert.AreEqual(replacedEntity.C, retrievedEntity.C); - Assert.AreEqual(null, retrievedEntity.D); - Assert.AreEqual(null, retrievedEntity.E); - Assert.AreEqual(null, retrievedEntity.F); - } - - [TestMethod] - [Description("Single Entity Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertOrReplaceAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - queryContext.MergeOption = MergeOption.NoTracking; - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - - // Insert Or Merge with no pre-existing entity - MergeEntity insertOrReplaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - insertOrReplaceEntity.Randomize(); - ctx.AttachTo(currentTable.Name, insertOrReplaceEntity, null); - ctx.UpdateObject(insertOrReplaceEntity); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - ctx.BeginSaveChangesWithRetries( - SaveChangesOptions.ReplaceOnUpdate, - (res) => - { - asyncRes = res; - evt.Set(); - }, - null); - evt.WaitOne(); - - ctx.EndSaveChangesWithRetries(asyncRes); - } - - ctx.Detach(insertOrReplaceEntity); - - // Retrieve Entity & Verify Contents - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(null, retrievedEntity.A); - Assert.AreEqual(null, retrievedEntity.B); - Assert.AreEqual(null, retrievedEntity.C); - Assert.AreEqual(insertOrReplaceEntity.D, retrievedEntity.D); - Assert.AreEqual(insertOrReplaceEntity.E, retrievedEntity.E); - Assert.AreEqual(insertOrReplaceEntity.F, retrievedEntity.F); - - BaseEntity replacedEntity = new BaseEntity("insert test", "foo"); - replacedEntity.Randomize(); - - ctx.AttachTo(currentTable.Name, replacedEntity, null); - ctx.UpdateObject(replacedEntity); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - ctx.BeginSaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - ctx.EndSaveChangesWithRetries(asyncRes); - } - - // Retrieve Entity & Verify - retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replacedEntity.A, retrievedEntity.A); - Assert.AreEqual(replacedEntity.B, retrievedEntity.B); - Assert.AreEqual(replacedEntity.C, retrievedEntity.C); - Assert.AreEqual(null, retrievedEntity.D); - Assert.AreEqual(null, retrievedEntity.E); - Assert.AreEqual(null, retrievedEntity.F); - } - - [TestMethod] - [Description("Test Table Save Changes Retry Basic APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextSaveChangeWithRetriesAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Get data context. - TableServiceContext context = tableClient.GetTableServiceContext(); - - // Create the new entity. - BaseEntity entity = new BaseEntity("Hello", "world."); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Add the entity. - context.AttachTo(this.currentTable.Name, entity); - context.UpdateObject(entity); - - // Save changes to the service. - IAsyncResult result = context.BeginSaveChangesWithRetries(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - context.EndSaveChangesWithRetries(result); - - BaseEntity entity2 = new BaseEntity("Insert", "foo."); - context.AttachTo(this.currentTable.Name, entity2); - context.UpdateObject(entity2); - - // Test again with different parameters - result = context.BeginSaveChangesWithRetries(SaveChangesOptions.None, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - context.EndSaveChangesWithRetries(result); - - // Retrieve Entities & Verify - BaseEntity retrievedEntity = (from ent in context.CreateQuery(currentTable.Name) - where - ent.PartitionKey == entity2.PartitionKey - && ent.RowKey == entity2.RowKey - select ent).AsTableServiceQuery(context).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - - retrievedEntity = (from ent in context.CreateQuery(currentTable.Name) - where - ent.PartitionKey == entity.PartitionKey - && ent.RowKey == entity.RowKey - select ent).AsTableServiceQuery(context).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - } - - // Test Dispose - context.Dispose(); - } - -#if TASK - [TestMethod] - [Description("Single Entity Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertOrReplaceTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - queryContext.MergeOption = MergeOption.NoTracking; - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - - // Insert Or Merge with no pre-existing entity - MergeEntity insertOrReplaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - insertOrReplaceEntity.Randomize(); - ctx.AttachTo(currentTable.Name, insertOrReplaceEntity, null); - ctx.UpdateObject(insertOrReplaceEntity); - ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.ReplaceOnUpdate).Wait(); - ctx.Detach(insertOrReplaceEntity); - - // Retrieve Entity & Verify Contents - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(null, retrievedEntity.A); - Assert.AreEqual(null, retrievedEntity.B); - Assert.AreEqual(null, retrievedEntity.C); - Assert.AreEqual(insertOrReplaceEntity.D, retrievedEntity.D); - Assert.AreEqual(insertOrReplaceEntity.E, retrievedEntity.E); - Assert.AreEqual(insertOrReplaceEntity.F, retrievedEntity.F); - - BaseEntity replacedEntity = new BaseEntity("insert test", "foo"); - replacedEntity.Randomize(); - - ctx.AttachTo(currentTable.Name, replacedEntity, null); - ctx.UpdateObject(replacedEntity); - ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.ReplaceOnUpdate).Wait(); - - // Retrieve Entity & Verify - retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replacedEntity.A, retrievedEntity.A); - Assert.AreEqual(replacedEntity.B, retrievedEntity.B); - Assert.AreEqual(replacedEntity.C, retrievedEntity.C); - Assert.AreEqual(null, retrievedEntity.D); - Assert.AreEqual(null, retrievedEntity.E); - Assert.AreEqual(null, retrievedEntity.F); - } -#endif - - #endregion - - #region Delete - - [TestMethod] - [Description("Single Entity Delete")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityDelete() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetries(); - - // Retrieve Entity - - ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == insertEntity.PartitionKey - && ent.RowKey == insertEntity.RowKey - select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); - Assert.IsNotNull(retrievedEntity); - ctx.DeleteObject(retrievedEntity); - ctx.SaveChangesWithRetries(); - - try - { - // Retrieve Entity - retrievedEntity = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == insertEntity.PartitionKey - && ent.RowKey == insertEntity.RowKey - select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.NotFound); - } - } - - [TestMethod] - [Description("Single Entity Delete Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertDeleteFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Delete Entity that does not exits - ComplexEntity deleteEntity = new ComplexEntity("insert test", "foo"); - ctx.AttachTo(currentTable.Name, deleteEntity, "*"); - ctx.DeleteObject(deleteEntity); - OperationContext opContext = new OperationContext(); - - try - { - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - - - ctx = tableClient.GetTableServiceContext(); - TableServiceContext ctx2 = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetries(); - - // Update Entity - ComplexEntity retrievedEntity = (from ent in ctx2.CreateQuery(currentTable.Name) - where ent.PartitionKey == insertEntity.PartitionKey - && ent.RowKey == insertEntity.RowKey - select ent).AsTableServiceQuery(ctx2).Execute().FirstOrDefault(); - - retrievedEntity.String = "updated value"; - - ctx2.UpdateObject(retrievedEntity); - ctx2.SaveChangesWithRetries(); - - // Now delete old reference with stale etag and validate exception - ctx.DeleteObject(insertEntity); - - opContext = new OperationContext(); - try - { - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met."}); - } - } - - #endregion - - #region Merge - - [TestMethod] - [Description("Single Entity Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - baseEntity.Randomize(); - ctx.AddObject(currentTable.Name, baseEntity); - ctx.SaveChangesWithRetries(); - string etag = ctx.Entities.First().ETag; - ctx.Detach(baseEntity); - - MergeEntity mergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - mergeEntity.Randomize(); - ctx.AttachTo(currentTable.Name, mergeEntity, etag); - ctx.UpdateObject(mergeEntity); - ctx.SaveChangesWithRetries(); - - // Retrieve Entity - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(baseEntity.A, retrievedEntity.A); - Assert.AreEqual(baseEntity.B, retrievedEntity.B); - Assert.AreEqual(baseEntity.C, retrievedEntity.C); - Assert.AreEqual(mergeEntity.D, retrievedEntity.D); - Assert.AreEqual(mergeEntity.E, retrievedEntity.E); - Assert.AreEqual(mergeEntity.F, retrievedEntity.F); - } - - [TestMethod] - [Description("Single Entity Merge Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityMergeFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext secondContext = tableClient.GetTableServiceContext(); - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - baseEntity.Randomize(); - ctx.AddObject(currentTable.Name, baseEntity); - ctx.SaveChangesWithRetries(); - string etag = ctx.Entities.First().ETag; - baseEntity.A = "updated"; - ctx.UpdateObject(baseEntity); - ctx.SaveChangesWithRetries(); - - MergeEntity mergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - mergeEntity.Randomize(); - secondContext.AttachTo(currentTable.Name, mergeEntity, etag); - secondContext.UpdateObject(mergeEntity); - OperationContext opContext = new OperationContext(); - - try - { - secondContext.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - ctx.DeleteObject(baseEntity); - ctx.SaveChangesWithRetries(); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - secondContext.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region Replace - - [TestMethod] - [Description("Single Entity Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - baseEntity.Randomize(); - ctx.AddObject(currentTable.Name, baseEntity); - ctx.SaveChangesWithRetries(); - string etag = ctx.Entities.First().ETag; - ctx.Detach(baseEntity); - - MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - replaceEntity.Randomize(); - ctx.AttachTo(currentTable.Name, replaceEntity, etag); - ctx.UpdateObject(replaceEntity); - ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); - - // Retrieve Entity - UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery(currentTable.Name) - where ent.PartitionKey == baseEntity.PartitionKey - && ent.RowKey == baseEntity.RowKey - select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(null, retrievedEntity.A); - Assert.AreEqual(null, retrievedEntity.B); - Assert.AreEqual(null, retrievedEntity.C); - Assert.AreEqual(replaceEntity.D, retrievedEntity.D); - Assert.AreEqual(replaceEntity.E, retrievedEntity.E); - Assert.AreEqual(replaceEntity.F, retrievedEntity.F); - } - - [TestMethod] - [Description("Single Entity Replace Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityReplaceFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - TableServiceContext secondContext = tableClient.GetTableServiceContext(); - - // Insert Entity - BaseEntity baseEntity = new BaseEntity("insert test", "foo"); - baseEntity.Randomize(); - ctx.AddObject(currentTable.Name, baseEntity); - ctx.SaveChangesWithRetries(); - string etag = ctx.Entities.First().ETag; - baseEntity.A = "updated"; - ctx.UpdateObject(baseEntity); - ctx.SaveChangesWithRetries(); - - MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); - replaceEntity.Randomize(); - secondContext.AttachTo(currentTable.Name, replaceEntity, etag); - secondContext.UpdateObject(replaceEntity); - OperationContext opContext = new OperationContext(); - - try - { - secondContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - ctx.DeleteObject(baseEntity); - ctx.SaveChangesWithRetries(); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - secondContext.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - #endregion - - #region Batch - - [TestMethod] - [Description("Batch Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BatchInsert() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entities - SortedDictionary entities = new SortedDictionary(); - for (int i = 0; i < 100; i++) - { - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + i); - entities.Add(insertEntity.RowKey, insertEntity); - ctx.AddObject(currentTable.Name, insertEntity); - } - - DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode); - - // Retrieve Entities - List retrievedEntities = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == entities.First().Value.PartitionKey - select ent).AsTableServiceQuery(ctx).Execute().ToList(); - - Assert.AreEqual(entities.Count, retrievedEntities.Count); - - foreach (ComplexEntity retrievedEntity in retrievedEntities) - { - ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity); - entities.Remove(retrievedEntity.RowKey); - } - - Assert.AreEqual(0, entities.Count); - } - - [TestMethod] - [Description("Batch Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BatchInsertAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entities - SortedDictionary entities = new SortedDictionary(); - for (int i = 0; i < 100; i++) - { - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + i); - entities.Add(insertEntity.RowKey, insertEntity); - ctx.AddObject(currentTable.Name, insertEntity); - } - - DataServiceResponse response; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - ctx.BeginSaveChangesWithRetries(SaveChangesOptions.Batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - response = ctx.EndSaveChangesWithRetries(asyncRes); - } - - Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode); - - // Retrieve Entities - List retrievedEntities = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == entities.First().Value.PartitionKey - select ent).AsTableServiceQuery(ctx).Execute().ToList(); - - Assert.AreEqual(entities.Count, retrievedEntities.Count); - - foreach (ComplexEntity retrievedEntity in retrievedEntities) - { - ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity); - entities.Remove(retrievedEntity.RowKey); - } - - Assert.AreEqual(0, entities.Count); - } - -#if TASK - [TestMethod] - [Description("Batch Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BatchInsertTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entities - SortedDictionary entities = new SortedDictionary(); - for (int i = 0; i < 100; i++) - { - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + i); - entities.Add(insertEntity.RowKey, insertEntity); - ctx.AddObject(currentTable.Name, insertEntity); - } - - DataServiceResponse response = ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.Batch).Result; - Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode); - - // Retrieve Entities - List retrievedEntities = (from ent in ctx.CreateQuery(currentTable.Name) - where ent.PartitionKey == entities.First().Value.PartitionKey - select ent).AsTableServiceQuery(ctx).Execute().ToList(); - - Assert.AreEqual(entities.Count, retrievedEntities.Count); - - foreach (ComplexEntity retrievedEntity in retrievedEntities) - { - ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity); - entities.Remove(retrievedEntity.RowKey); - } - - Assert.AreEqual(0, entities.Count); - } -#endif - - #endregion - - #region Insert Negative Tests - - [TestMethod] - [Description("Single Entity Insert Entity over 1 MB")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SingleEntityInsertEntityOver1MB() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); - insertEntity.Binary = new byte[1024 * 1024]; - ctx.AddObject(currentTable.Name, insertEntity); - OperationContext opContext = new OperationContext(); - - try - { - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than allowed by the Table Service."); - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableRetryTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableRetryTests.cs deleted file mode 100644 index 7d5ed94db2102..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableRetryTests.cs +++ /dev/null @@ -1,373 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Linq; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - [TestClass] - public class TableRetryTests : TableTestBase - { - #region Locals + Ctors - public TableRetryTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - } - - #endregion - - #region Save Changes Retry Tests - - [TestMethod] - [Description("Test Table Save Changes Retry APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextSaveChangesRetryAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - insertEntity.Binary = new byte[20 * 1024]; - ctx.AddObject(currentTable.Name, insertEntity); - } - - TestHelper.ExecuteAPMMethodWithRetry(3, - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 500 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (options, opContext, callback, state) => ctx.BeginSaveChangesWithRetries(SaveChangesOptions.Batch, (TableRequestOptions)options, opContext, callback, state), - (res) => ctx.EndSaveChangesWithRetries(res)); - } - - [TestMethod] - [Description("Test Table Save Changes Retry Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextSaveChangesRetrySync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - insertEntity.Binary = new byte[20 * 1024]; - ctx.AddObject(currentTable.Name, insertEntity); - } - - TestHelper.ExecuteMethodWithRetry( - 3, - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 500 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (options, opContext) => ctx.SaveChangesWithRetries(SaveChangesOptions.Batch, (TableRequestOptions)options, opContext)); - } - - #endregion - - #region TableServiceQuery Retry Tests - - [TestMethod] - [Description("Test TableServiceQuery Retry Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryWithRetrySync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 1500; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - - if ((m + 1) % 100 == 0) - { - ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - } - } - - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - TestHelper.ExecuteMethodWithRetry( - 4, // 2 segments, 2 failures - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true), - new BehaviorOptions(4)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true), - new BehaviorOptions(4)) - }, - (options, opContext) => query.Execute((TableRequestOptions)options, opContext).ToList()); - } - - [TestMethod] - [Description("Test TableServiceQuery APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryWithRetryAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 1000; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - - if ((m + 1) % 100 == 0) - { - ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - } - } - - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - TestHelper.ExecuteAPMMethodWithRetry( - 2, // 1 failure, one success - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)) - }, - (options, opContext, callback, state) => query.BeginExecuteSegmented(null, (TableRequestOptions)options, opContext, callback, state), - query.EndExecuteSegmented); - } - -#if TASK - [TestMethod] - [Description("Test TableServiceQuery Retry Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryWithRetryTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 1000; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - - if ((m + 1) % 100 == 0) - { - ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.Batch).Wait(); - } - } - - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - TestHelper.ExecuteTaskMethodWithRetry( - 2, // 1 failure, one success - new[] - { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay( - 10000, - XStoreSelectors.TableTraffic() - .IfHostNameContains(tableClient.Credentials.AccountName) - .Alternating(true)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter( - Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic() - .IfHostNameContains(tableClient.Credentials.AccountName) - .Alternating(true)) - }, - (options, opContext) => query.ExecuteSegmentedAsync(null, (TableRequestOptions)options, opContext)); - } -#endif - - #endregion - - #region Exception Cases - [TestMethod] - [Description("Test to ensure client side deserialization errors are not retried")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryEntityTypeMismatchNotRetryableSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - // Insert Entity - ComplexEntity insertEntity = new ComplexEntity("insert test", m.ToString()); - ctx.AddObject(currentTable.Name, insertEntity); - } - - ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - - OperationContext opContext = new OperationContext(); - try - { - //This query will throw since it is of a different type then the tracked entities in the context - List query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx).Execute(null, opContext).ToList(); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.AssertNAttempts(opContext, 1); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Test to ensure Entity Conflict exceptions do not retry")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSaveChangesConflictDoesNotRetry() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - ComplexEntity insertEntity = new ComplexEntity("insert test", "conflict"); - ctx.AddObject(currentTable.Name, insertEntity); - ctx.SaveChangesWithRetries(); - - - OperationContext opContext = new OperationContext(); - try - { - TableServiceContext ctx2 = tableClient.GetTableServiceContext(); - ctx2.AddObject(currentTable.Name, insertEntity); - ctx2.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.AssertNAttempts(opContext, 1); - } - catch (Exception) - { - Assert.Fail(); - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceContextUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceContextUnitTests.cs deleted file mode 100644 index 5ec5e43c074c3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceContextUnitTests.cs +++ /dev/null @@ -1,551 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Diagnostics; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - /// - /// Summary description for TableServiceContextUnitTests - /// - [TestClass] - public class TableServiceContextUnitTests : TableTestBase - { - #region Ctors + Locals - public TableServiceContextUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - static CloudTable currentTable = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext){} - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - } - - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - } - #endregion - - #region RequestResults - - [TestMethod] - [Description("TableServiceContext RequestResults - Verifies one Request Result is generated for each entity inserted using a non batch save changes.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextRequestResultsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - - TestHelper.AssertNAttempts(opContext, 10); - } - - [TestMethod] - [Description("TableServiceContext RequestResults - Verifies one Request Result is generated for each entity inserted using a non batch save changes. APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextRequestResultsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, - (res) => - { - ctx.EndSaveChangesWithRetries(res); - evt.Set(); - }, null); - evt.WaitOne(); - } - - TestHelper.AssertNAttempts(opContext, 10); - } - -#if TASK - [TestMethod] - [Description("TableServiceContext RequestResults - Verifies one Request Result is generated for each entity inserted using a non batch save changes.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextRequestResultsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - - ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.None, null, opContext).Wait(); - - TestHelper.AssertNAttempts(opContext, 10); - } -#endif - #endregion - - #region Send + Receive events - - [TestMethod] - [Description("TableServiceContext OperationContextEvents - Verifies Send and Receive events for opcontext Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextOperationContextEvents() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - List sends = new List(); - List receives = new List(); - - OperationContext opContext = new OperationContext(); - opContext.SendingRequest += (sender, args) => sends.Add(args.RequestInformation.StartTime.Ticks.ToString()); - opContext.ResponseReceived += (sender, args) => receives.Add(args.RequestInformation.ServiceRequestID); - - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - - TestHelper.AssertNAttempts(opContext, 10); - - Assert.AreEqual(sends.Count(), 10); - Assert.AreEqual(receives.Count(), 10); - } - - [TestMethod] - [Description("TableServiceContext OperationContextEvents - Verifies Send and Receive events for opcontext APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextOperationContextEventsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - List sends = new List(); - List receives = new List(); - - OperationContext opContext = new OperationContext(); - opContext.SendingRequest += (sender, args) => sends.Add(args.RequestInformation.StartTime.Ticks.ToString()); - opContext.ResponseReceived += (sender, args) => receives.Add(args.RequestInformation.ServiceRequestID); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, - (res) => - { - ctx.EndSaveChangesWithRetries(res); - evt.Set(); - }, null); - evt.WaitOne(); - } - - TestHelper.AssertNAttempts(opContext, 10); - - Assert.AreEqual(sends.Count(), 10); - Assert.AreEqual(receives.Count(), 10); - } - #endregion - - #region Start + End Time - - [TestMethod] - [Description("TableServiceContext OperationContext StartEndTime")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextOperationContextStartEndTime() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - DateTime start = DateTime.Now; - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); - - Assert.IsNotNull(opContext.StartTime, "StartTime not set"); - Assert.IsTrue(opContext.StartTime >= start, "StartTime not set correctly"); - Assert.IsNotNull(opContext.EndTime, "EndTime not set"); - Assert.IsTrue(opContext.EndTime <= DateTime.Now, "EndTime not set correctly"); - } - - [TestMethod] - [Description("TableServiceContext OperationContext StartEndTime APM ")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextOperationContextStartEndTimeAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - DateTime start = DateTime.Now; - for (int m = 0; m < 10; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - - OperationContext opContext = new OperationContext(); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, - (res) => - { - ctx.EndSaveChangesWithRetries(res); - evt.Set(); - }, null); - evt.WaitOne(); - } - - Assert.IsNotNull(opContext.StartTime, "StartTime not set"); - Assert.IsTrue(opContext.StartTime >= start, "StartTime not set correctly"); - Assert.IsNotNull(opContext.EndTime, "EndTime not set"); - Assert.IsTrue(opContext.EndTime <= DateTime.Now, "EndTime not set correctly"); - } - #endregion - - #region ConcurrencyTests - - [TestMethod] - [Description("TableServiceContext Concurrency Should allow only one in flight operation at any given time.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextConcurrencyAllowsOnlySingleOperationAtOnce() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext tableContext = tableClient.GetTableServiceContext(); - - // insert entities to query against - for (int i = 0; i < 5; i++) - { - for (int m = 0; m < 100; m++) - { - BaseEntity ent = new BaseEntity("testpartition" + i, m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - tableContext.AddObject(currentTable.Name, ent); - } - - tableContext.SaveChangesWithRetries(SaveChangesOptions.Batch); - } - - List opContexts = new List(); - object lockerObj = new object(); - DateTime start = DateTime.Now; - - int threadsRunning = 0; - - Exception lastEx = null; - - // Start 10 simultaneous threads to query entities associated with same context. - for (int j = 0; j < 10; j++) - { - opContexts.Add(new OperationContext()); - Thread newThread = new Thread((arg) => - { - Interlocked.Increment(ref threadsRunning); - try - { - lock (lockerObj) - { - Monitor.Wait(lockerObj); - } - - TableServiceQuery query = (from ent in tableContext.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(tableContext); - - Debug.WriteLine(String.Format("Thread {0} start operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); - - try - { - query.Execute(null, arg as OperationContext).ToList(); - } - catch (Exception) - { - // no op, expected to have some exceptions - } - - Debug.WriteLine(String.Format("Thread {0} end operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); - } - catch (Exception ex) - { - lastEx = ex; - } - finally - { - Interlocked.Decrement(ref threadsRunning); - } - }); - - newThread.Start(opContexts[j]); - } - - // Wait for all threads to start - while (Interlocked.CompareExchange(ref threadsRunning, 10, 10) < 10) - { - Thread.Sleep(200); - } - - // pulse all threads - lock (lockerObj) - { - Monitor.PulseAll(lockerObj); - } - - // Wait for all threads to complete - while (Interlocked.CompareExchange(ref threadsRunning, -1, 0) > -1) - { - Thread.Sleep(200); - } - - if (lastEx != null) - { - throw lastEx; - } - - foreach (OperationContext opContext in opContexts) - { - if (opContext.LastResult == null || opContext.LastResult.StartTime == null || opContext.LastResult.EndTime == null) - continue; - - TestHelper.AssertNAttempts(opContext, 1); - - RequestResult currRes = opContext.LastResult; - - // Make sure this results start time does not occur in between any other results start & end time - IEnumerable overlappingResults = (from ctx in opContexts - where ctx.LastResult != null && ctx.LastResult != currRes && - ctx.LastResult.StartTime != null && ctx.LastResult.EndTime != null && - ctx.LastResult.StartTime.Ticks < currRes.StartTime.Ticks && - ctx.LastResult.EndTime.Ticks > currRes.StartTime.Ticks - select ctx.LastResult); - - Assert.AreEqual(overlappingResults.Count(), 0, "Detected overlapping query"); - } - } - - #endregion - - #region Timeout in save changes - - [TestMethod] - [Description("TableServiceContext Ensure timeout is thrown during Save Changes with non batch. Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextTimeoutDuringSaveChangesNonBatchSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - TableRequestOptions requestOptions = new TableRequestOptions() { MaximumExecutionTime = TimeSpan.FromSeconds(5) }; - - using (HttpMangler proxy = new HttpMangler(false, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).SkipNSessions(10)) })) - { - try - { - ctx.SaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.RequestTimeout); - Assert.AreEqual("The client could not finish the operation within specified timeout.", ex.Message); - Assert.IsTrue(ex.InnerException is TimeoutException); - } - } - } - - [TestMethod] - [Description("TableServiceContext Ensure timeout is thrown during Save Changes with non batch. APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceContextTimeoutDuringSaveChangesNonBatchAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int m = 0; m < 100; m++) - { - BaseEntity ent = new BaseEntity("testpartition", m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - OperationContext opContext = new OperationContext(); - TableRequestOptions requestOptions = new TableRequestOptions() { MaximumExecutionTime = TimeSpan.FromSeconds(5) }; - - using (HttpMangler proxy = new HttpMangler(false, - new[] { DelayBehaviors.DelayAllRequestsIf(2000, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).SkipNSessions(10)) })) - { - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext, - (res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - ctx.EndSaveChangesWithRetries(result); - } - - ctx.SaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.RequestTimeout); - Assert.AreEqual("The client could not finish the operation within specified timeout.", ex.Message); - Assert.IsTrue(ex.InnerException is TimeoutException); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceQueryUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceQueryUnitTests.cs deleted file mode 100644 index 2f1e3df417c78..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/DataServices/TableServiceQueryUnitTests.cs +++ /dev/null @@ -1,445 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.DataServices.Entities; -using System; -using System.Collections.Generic; -using System.Data.Services.Client; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table.DataServices -{ - /// - /// Summary description for TableServiceQueryUnitTests - /// - [TestClass] - public class TableServiceQueryUnitTests : TableTestBase - { - #region Ctors + Locals - public TableServiceQueryUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - const int totalTestEntities = 1500; - static CloudTable currentTable = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - // Populate Entities (This will add 1500 entities to a new table, enough to test continuations - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - for (int l = 0; l < totalTestEntities / 100; l++) - { - for (int m = 0; m < 100; m++) - { - BaseEntity ent = new BaseEntity("partition" + l, m.ToString()); - ent.Randomize(); - ent.A = ent.RowKey; - ctx.AddObject(currentTable.Name, ent); - } - - ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExists(); - } - // - // Use TestInitialize to run code before running each test - // [TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - // [TestCleanup()] - // public void MyTestCleanup() { } - // - #endregion - - #region Execute - - [TestMethod] - [Description("TableServiceQuery Execute Basic Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteBasic() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - List totalResults = query.Execute().ToList(); - Assert.AreEqual(totalResults.Count, totalTestEntities); - } - - [TestMethod] - [Description("TableServiceQuery Execute With Take")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteWithTake() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - int takeCount = 0; - - IQueryable baseQuery = (from ent in ctx.CreateQuery(currentTable.Name) - select ent); - - List totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList(); - Assert.AreEqual(totalResults.Count, takeCount); - - takeCount = 10; - totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList(); - Assert.AreEqual(totalResults.Count, Math.Min(takeCount, totalTestEntities)); - - takeCount = 1000; - totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList(); - Assert.AreEqual(totalResults.Count, Math.Min(takeCount, totalTestEntities)); - - - - takeCount = 1001; - try - { - totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList(); - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest); - Assert.AreEqual(ex.Message, "InvalidInput"); - Assert.IsTrue(ex.RequestInformation.ExtendedErrorInformation.ErrorMessage.StartsWith("One of the request inputs is not valid."), ex.RequestInformation.ExtendedErrorInformation.ErrorMessage); - } - - - takeCount = -1; - try - { - totalResults = baseQuery.Take(takeCount).AsTableServiceQuery(ctx).Execute().ToList(); - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest); - Assert.AreEqual(ex.Message, "InvalidInput"); - Assert.IsTrue(ex.RequestInformation.ExtendedErrorInformation.ErrorMessage.StartsWith("One of the request inputs is not valid."), ex.RequestInformation.ExtendedErrorInformation.ErrorMessage); - } - } - - #endregion - - #region Execute Segmented - - #region Sync - - [TestMethod] - [Description("TableServiceQuery Execute Segmented Basic Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteSegmentedBasicSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - List totalResults = new List(); - TableQuerySegment segment = null; - - do - { - segment = query.ExecuteSegmented(segment != null ? segment.ContinuationToken : null); - if (totalResults.Count == 0) - { - // Assert first segment has continuation token - - Assert.IsNotNull(segment.ContinuationToken); - } - - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, totalTestEntities); - } - - [TestMethod] - [Description("TableServiceQuery Execute Segmented With Take")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteSegmentedWithTake() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - int takeCount = 150; - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).Take(takeCount).AsTableServiceQuery(ctx); - - List totalResults = new List(); - TableQuerySegment segment = null; - - int segmentCount = 0; - do - { - segment = query.ExecuteSegmented(segment != null ? segment.ContinuationToken : null); - if (totalResults.Count == 0) - { - // Assert first segment has continuation token - Assert.IsNotNull(segment.ContinuationToken); - } - - totalResults.AddRange(segment); - segmentCount++; - } - while (segment.ContinuationToken != null); - - Assert.IsTrue(segmentCount >= totalTestEntities / takeCount); - Assert.AreEqual(totalResults.Count, totalTestEntities); - } - - #endregion - - #region APM - - [TestMethod] - [Description("TableServiceQuery Execute Segmented Basic APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteSegmentedBasicAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - List totalResults = new List(); - TableQuerySegment segment = null; - - do - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - query.BeginExecuteSegmented(segment != null ? segment.ContinuationToken : null, - (res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - segment = query.EndExecuteSegmented(result); - } - - if (totalResults.Count == 0) - { - // Assert first segment has continuation token - - Assert.IsNotNull(segment.ContinuationToken); - } - - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, totalTestEntities); - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("TableServiceQuery Execute Segmented Basic Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryExecuteSegmentedBasicTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select ent).AsTableServiceQuery(ctx); - - List totalResults = new List(); - TableQuerySegment segment = null; - - do - { - segment = query.ExecuteSegmentedAsync(segment != null ? segment.ContinuationToken : null).Result; - if (totalResults.Count == 0) - { - // Assert first segment has continuation token - - Assert.IsNotNull(segment.ContinuationToken); - } - - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, totalTestEntities); - } -#endif - - #endregion - - #endregion - - #region Projection - - [TestMethod] - [Description("TableServiceQuery Projection")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryProjection() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select new UnionEnitity - { - A = ent.A, - RowKey = ent.RowKey - }).AsTableServiceQuery(ctx); - - List totalResults = query.Execute().ToList(); - Assert.AreEqual(totalResults.Count, totalTestEntities); - - foreach (UnionEnitity ent in totalResults) - { - Assert.IsNotNull(ent.A); - Assert.AreEqual(ent.A, ent.RowKey); - Assert.IsNull(ent.B); - Assert.IsNull(ent.C); - Assert.IsNull(ent.D); - Assert.IsNull(ent.E); - Assert.IsNull(ent.F); - } - } - - [TestMethod] - [Description("TableServiceQuery Projection With Update")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableServiceQueryProjectionWithUpdate() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableServiceContext ctx = tableClient.GetTableServiceContext(); - - // Retrieve Entities - TableServiceQuery query = (from ent in ctx.CreateQuery(currentTable.Name) - select new UnionEnitity - { - A = ent.A, - B = ent.B - }).Take(20).AsTableServiceQuery(ctx); - - - - List totalResults = query.Execute().ToList(); - - foreach (UnionEnitity ent in totalResults) - { - Assert.IsNotNull(ent.A); - Assert.IsNotNull(ent.B); - ent.PartitionKey = string.Empty; - ent.RowKey = string.Empty; - ent.B += "_updated"; - ctx.UpdateObject(ent); - } - - ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); - - TableServiceContext queryContext = tableClient.GetTableServiceContext(); - - // Verify update - TableServiceQuery secondQuery = (from ent in queryContext.CreateQuery(currentTable.Name) - select ent).Take(20).AsTableServiceQuery(queryContext); - foreach (BaseEntity ent in secondQuery.Execute()) - { - Assert.IsTrue(ent.B.EndsWith("_updated")); - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableRetryTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableRetryTests.cs deleted file mode 100644 index a1bf8417c8443..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/Table/TableRetryTests.cs +++ /dev/null @@ -1,327 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.RetryPolicies; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.Linq; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableRetryTests : TableTestBase - { - #region Locals + Ctors - public TableRetryTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Table Operation - - [TestMethod] - [Description("Test TableOperation Execute Retry")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationExecuteRetryAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", "foo"); - - for (int m = 0; m < 20; m++) - { - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[50 * 1024])); - } - - TestHelper.ExecuteAPMMethodWithRetry(3, - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 500 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (options, opContext, callback, state) => currentTable.BeginExecute(TableOperation.Insert(insertEntity), (TableRequestOptions)options, opContext, callback, state), - (res) => currentTable.EndExecute(res)); - } - - [TestMethod] - [Description("Test Table Save Changes Retry Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationExecuteRetrySync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", "foo"); - - for (int m = 0; m < 20; m++) - { - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[50 * 1024])); - } - - TestHelper.ExecuteMethodWithRetry( - 3, - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 500 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (options, opContext) => currentTable.Execute(TableOperation.Insert(insertEntity), (TableRequestOptions)options, opContext)); - } - - #endregion - - #region TableQuery Retry Tests - - [TestMethod] - [Description("Test TableQuery Retry Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithRetrySync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - - for (int m = 0; m < 1500; m++) - { - // Insert Entity - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", m.ToString()); - batch.Insert(insertEntity); - - if ((m + 1) % 100 == 0) - { - currentTable.ExecuteBatch(batch); - batch = new TableBatchOperation(); - } - } - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "insert test")); - - TestHelper.ExecuteMethodWithRetry( - 4, // 2 segments, 2 failures - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true), - new BehaviorOptions(4)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true), - new BehaviorOptions(4)) - }, - (options, opContext) => currentTable.ExecuteQuery(query, (TableRequestOptions)options, opContext).ToList()); - } - - [TestMethod] - [Description("Test TableQuery APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithRetryAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - - for (int m = 0; m < 1500; m++) - { - // Insert Entity - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", m.ToString()); - insertEntity.Properties.Add("prop" + m.ToString(), new EntityProperty(new byte[1 * 1024])); - batch.Insert(insertEntity); - - if ((m + 1) % 100 == 0) - { - currentTable.ExecuteBatch(batch); - batch = new TableBatchOperation(); - } - } - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "insert test")); - - TestHelper.ExecuteAPMMethodWithRetry( - 2, // 1 failure, one success - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)) - }, - (options, opContext, callback, state) => currentTable.BeginExecuteQuerySegmented(query, null, (TableRequestOptions)options, opContext, callback, state), - (res) => currentTable.EndExecuteQuerySegmented(res)); - } - - #endregion - - #region Exception Cases - - [TestMethod] - [Description("Test to ensure Entity Conflict exceptions do not retry")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationConflictDoesNotRetry() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", "foo"); - currentTable.Execute(TableOperation.Insert(insertEntity)); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.Execute(TableOperation.Insert(insertEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.AssertNAttempts(opContext, 1); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Test to ensure setting NoRetry on client does not retry")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationNoRetry() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.RetryPolicy = new NoRetry(); - CloudTable currentTable = tableClient.GetTableReference("noretrytable"); - currentTable.CreateIfNotExists(); - DynamicTableEntity insertEntity = new DynamicTableEntity("insert test", "foo"); - currentTable.Execute(TableOperation.Insert(insertEntity)); - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "insert test")); - try - { - TestHelper.ExecuteMethodWithRetry( - 1, - new[] { - //Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertDownstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).Alternating(true)) - }, - (options, opContext) => currentTable.ExecuteQuery(query, (TableRequestOptions)options, opContext).ToList()); - } - catch (StorageException ex) - { - Assert.IsTrue(ex.RequestInformation.HttpStatusCode == 503); - } - finally - { - currentTable.DeleteIfExists(); - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/WCFBufferManagerAdapter.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/WCFBufferManagerAdapter.cs deleted file mode 100644 index b9e0d3ee7c52c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNet40/WCFBufferManagerAdapter.cs +++ /dev/null @@ -1,66 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System.ServiceModel.Channels; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage -{ - public class WCFBufferManagerAdapter : IBufferManager - { - private int defaultBufferSize = 0; - - public WCFBufferManagerAdapter(BufferManager manager, int defaultBufferSize) - { - this.Manager = manager; - this.defaultBufferSize = defaultBufferSize; - } - - private int outstandingBufferCount = 0; - public int OutstandingBufferCount - { - get - { - return Interlocked.CompareExchange(ref outstandingBufferCount, 0, 0); - } - - set - { - Interlocked.Exchange(ref outstandingBufferCount, value); - } - } - - public BufferManager Manager { get; internal set; } - - public void ReturnBuffer(byte[] buffer) - { - Interlocked.Decrement(ref outstandingBufferCount); - this.Manager.ReturnBuffer(buffer); - } - - public byte[] TakeBuffer(int bufferSize) - { - Interlocked.Increment(ref outstandingBufferCount); - return this.Manager.TakeBuffer(bufferSize); - } - - public int GetDefaultBufferSize() - { - return this.defaultBufferSize; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobAnalyticsUnitTests.cs deleted file mode 100644 index b7b16c9af9ac5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobAnalyticsUnitTests.cs +++ /dev/null @@ -1,558 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public BlobAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudBlobClient client = GenerateCloudBlobClient(); - startProperties = client.GetServiceProperties(); - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.SetServiceProperties(startProperties); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - #region Sync - - [TestMethod] - [Description("Test Analytics Round Trip Sync")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsRoundTripSync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Analytics Round Trip APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsRoundTripAPM() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginSetServiceProperties(props, (res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - client.EndSetServiceProperties(result); - } - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - - ServiceProperties retrievedProps = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginGetServiceProperties((res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - retrievedProps = client.EndGetServiceProperties(result); - } - - AssertServicePropertiesAreEqual(props, retrievedProps); - } - - #endregion - -#region TASK - [TestMethod] - [Description("Test Analytics Round Trip Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsRoundTripTask() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServicePropertiesAsync(props).Wait(); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServicePropertiesAsync().Result); - } - - [TestMethod] - [Description("Test Blob GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobGetSetServicePropertiesTask() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 8; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 8; - serviceProperties.Metrics.Version = "1.0"; - - blobClient.SetServicePropertiesAsync(serviceProperties).Wait(); - - ServiceProperties actual = blobClient.GetServicePropertiesAsync().Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Blob GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobGetSetServicePropertiesCancellationTokenTask() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CancellationToken cancellationToken = CancellationToken.None; - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 9; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 9; - serviceProperties.Metrics.Version = "1.0"; - - blobClient.SetServicePropertiesAsync(serviceProperties, cancellationToken).Wait(); - - ServiceProperties actual = blobClient.GetServicePropertiesAsync(cancellationToken).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Blob GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobGetSetServicePropertiesRequestOptionsOperationContextTask() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - BlobRequestOptions requestOptions = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 10; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 10; - serviceProperties.Metrics.Version = "1.0"; - - blobClient.SetServicePropertiesAsync(serviceProperties, requestOptions, operationContext).Wait(); - - ServiceProperties actual = blobClient.GetServicePropertiesAsync(requestOptions, operationContext).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Blob GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobGetSetServicePropertiesRequestOptionsOperationContextCancellationTokenTask() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - BlobRequestOptions requestOptions = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 11; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 11; - serviceProperties.Metrics.Version = "1.0"; - - blobClient.SetServicePropertiesAsync(serviceProperties, requestOptions, operationContext, cancellationToken).Wait(); - - ServiceProperties actual = blobClient.GetServicePropertiesAsync(requestOptions, operationContext, cancellationToken).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } -#endregion - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsDisable() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Default Service Version")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsDefaultServiceVersion() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = client.GetServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - props.DefaultServiceVersion = "2011-08-18"; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - props.DefaultServiceVersion = "2012-02-12"; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - props.DefaultServiceVersion = null; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsLoggingOperations() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsMetricsLevel() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobTestAnalyticsRetentionPolicies() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - // Wait for analytics server to update - Thread.Sleep(60 * 1000); - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobCancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobCancellationUnitTests.cs deleted file mode 100644 index 6a689c150876f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobCancellationUnitTests.cs +++ /dev/null @@ -1,177 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobCancellationUnitTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Cancel blob download to stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamAPMCancel() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext operationContext = new OperationContext(); - result = blob.BeginDownloadToStream(downloadedBlob, null, null, operationContext, - ar => waitHandle.Set(), - null); - Thread.Sleep(100); - result.Cancel(); - waitHandle.WaitOne(); - try - { - blob.EndDownloadToStream(result); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.Message, "Operation was canceled by user."); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 306); - Assert.AreEqual(ex.RequestInformation.HttpStatusMessage, "Unused"); - } - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Cancel upload from stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamAPMCancel() - { - byte[] buffer = GetRandomBuffer(24 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - OperationContext operationContext = new OperationContext(); - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, null, null, operationContext, - ar => waitHandle.Set(), - null); - Thread.Sleep(500); - result.Cancel(); - waitHandle.WaitOne(); - try - { - blob.EndUploadFromStream(result); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.Message, "Operation was canceled by user."); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 306); - Assert.AreEqual(ex.RequestInformation.HttpStatusMessage, "Unused"); - } - - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetMetadataAPMCancel() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - container.Metadata.Add("key1", "value1"); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.BlobTraffic().IfHostNameContains(container.ServiceClient.Credentials.AccountName)) }, - (options, opContext, callback, state) => container.BeginSetMetadata(null, (BlobRequestOptions)options, opContext, callback, state), - container.EndSetMetadata); - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobManglerUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobManglerUnitTests.cs deleted file mode 100644 index 9ca6e62923ae5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobManglerUnitTests.cs +++ /dev/null @@ -1,207 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobManglerUnitTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Force blob download to retry")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamAPMRetry() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - Exception manglerEx = null; - using (HttpMangler proxy = new HttpMangler(false, - new[] - { - TamperBehaviors.TamperNRequestsIf( - session => ThreadPool.QueueUserWorkItem(state => - { - Thread.Sleep(1000); - try - { - session.Abort(); - } - catch (Exception e) - { - manglerEx = e; - } - }), - 2, - XStoreSelectors.BlobTraffic().IfHostNameContains(container.ServiceClient.Credentials.AccountName)) - })) - { - OperationContext operationContext = new OperationContext(); - result = blob.BeginDownloadToStream(downloadedBlob, null, null, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - - if (manglerEx != null) - { - throw manglerEx; - } - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Force range blob download to retry")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToStreamAPMRetry() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - int offset = 1024; - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - } - - using (MemoryStream originalBlob = new MemoryStream()) - { - originalBlob.Write(buffer, offset, buffer.Length - offset); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - using (MemoryStream downloadedBlob = new MemoryStream()) - { - Exception manglerEx = null; - using (HttpMangler proxy = new HttpMangler(false, - new[] - { - TamperBehaviors.TamperNRequestsIf( - session => ThreadPool.QueueUserWorkItem(state => - { - Thread.Sleep(1000); - try - { - session.Abort(); - } - catch (Exception e) - { - manglerEx = e; - } - }), - 2, - XStoreSelectors.BlobTraffic().IfHostNameContains(container.ServiceClient.Credentials.AccountName)) - })) - { - OperationContext operationContext = new OperationContext(); - BlobRequestOptions options = new BlobRequestOptions() - { - UseTransactionalMD5 = true - }; - - ICancellableAsyncResult result = blob.BeginDownloadRangeToStream(downloadedBlob, offset, buffer.Length - offset, null, options, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - - if (manglerEx != null) - { - throw manglerEx; - } - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobReadStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobReadStreamTest.cs deleted file mode 100644 index 17bf06561538e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobReadStreamTest.cs +++ /dev/null @@ -1,855 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.IO; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobReadStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Validate StreamMinimumReadSizeInBytes property")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadStreamReadSizeTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - BlobReadStreamReadSizeTest(blob); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Validate StreamMinimumReadSizeInBytes property")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadStreamReadSizeTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - BlobReadStreamReadSizeTest(blob); - } - finally - { - container.DeleteIfExists(); - } - } - - private void BlobReadStreamReadSizeTest(ICloudBlob blob) - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - TestHelper.ExpectedException( - () => blob.StreamMinimumReadSizeInBytes = 16 * 1024 - 1, - "StreamMinimumReadSizeInBytes should not accept values smaller than 16KB"); - - blob.StreamMinimumReadSizeInBytes = 4 * 1024 * 1024 + 1; - BlobRequestOptions options = new BlobRequestOptions() { UseTransactionalMD5 = true }; - TestHelper.ExpectedException( - () => blob.OpenRead(null, options, null), - "StreamMinimumReadSizeInBytes should be smaller than 4MB if UseTransactionalMD5 is true"); - - string range = null; - OperationContext context = new OperationContext(); - context.SendingRequest += (sender, e) => range = range ?? e.Request.Headers["x-ms-range"]; - - blob.StreamMinimumReadSizeInBytes = 4 * 1024 * 1024; - using (Stream blobStream = blob.OpenRead(null, options, context)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (blob.StreamMinimumReadSizeInBytes - 1).ToString(), range); - range = null; - } - - blob.StreamMinimumReadSizeInBytes = 6 * 1024 * 1024; - options.UseTransactionalMD5 = false; - using (Stream blobStream = blob.OpenRead(null, options, context)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (buffer.Length - 1).ToString(), range); - range = null; - } - - blob.StreamMinimumReadSizeInBytes = 16 * 1024; - using (Stream blobStream = blob.OpenRead(null, options, context)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (blob.StreamMinimumReadSizeInBytes - 1).ToString(), range); - range = null; - } - } - - [TestMethod] - [Description("Validate StreamMinimumReadSizeInBytes property")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadStreamReadSizeTestAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - BlobReadStreamReadSizeTestAPM(blob); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Validate StreamMinimumReadSizeInBytes property")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadStreamReadSizeTestAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - BlobReadStreamReadSizeTestAPM(blob); - } - finally - { - container.DeleteIfExists(); - } - } - - private void BlobReadStreamReadSizeTestAPM(ICloudBlob blob) - { - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - result = blob.BeginUploadFromStream(wholeBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - - TestHelper.ExpectedException( - () => blob.StreamMinimumReadSizeInBytes = 16 * 1024 - 1, - "StreamMinimumReadSizeInBytes should not accept values smaller than 16KB"); - - blob.StreamMinimumReadSizeInBytes = 4 * 1024 * 1024 + 1; - BlobRequestOptions options = new BlobRequestOptions() { UseTransactionalMD5 = true }; - result = blob.BeginOpenRead(null, options, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndOpenRead(result), - "StreamMinimumReadSizeInBytes should be smaller than 4MB if UseTransactionalMD5 is true"); - - string range = null; - OperationContext context = new OperationContext(); - context.SendingRequest += (sender, e) => range = range ?? e.Request.Headers["x-ms-range"]; - - blob.StreamMinimumReadSizeInBytes = 4 * 1024 * 1024; - result = blob.BeginOpenRead(null, options, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (blob.StreamMinimumReadSizeInBytes - 1).ToString(), range); - range = null; - } - - blob.StreamMinimumReadSizeInBytes = 6 * 1024 * 1024; - options.UseTransactionalMD5 = false; - result = blob.BeginOpenRead(null, options, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (buffer.Length - 1).ToString(), range); - range = null; - } - - blob.StreamMinimumReadSizeInBytes = 16 * 1024; - result = blob.BeginOpenRead(null, options, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - blobStream.ReadByte(); - Assert.AreEqual("bytes=0-" + (blob.StreamMinimumReadSizeInBytes - 1).ToString(), range); - range = null; - } - } - } - - [TestMethod] - [Description("Download a blob using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadStreamBasicTest() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - using (Stream blobStream = blob.OpenRead()) - { - TestHelper.AssertStreamsAreEqual(wholeBlob, blobStream); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Download a blob using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadStreamBasicTest() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - using (Stream blobStream = blob.OpenRead()) - { - TestHelper.AssertStreamsAreEqual(wholeBlob, blobStream); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadLockToETagTest() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (Stream blobStream = blob.OpenRead()) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - using (Stream blobStream = blob.OpenRead()) - { - long length = blobStream.Length; - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blob.OpenRead(accessCondition), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadLockToETagTestAPM() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginOpenRead( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - result = blob.BeginOpenRead( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - long length = blobStream.Length; - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadata(); - result = blob.BeginOpenRead( - accessCondition, - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndOpenRead(result), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadLockToETagTestTask() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(wholeBlob).Wait(); - } - - using (Stream blobStream = blob.OpenReadAsync().Result) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - using (Stream blobStream = blob.OpenReadAsync().Result) - { - long length = blobStream.Length; - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedExceptionTask( - blob.OpenReadAsync(accessCondition, null, null), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadLockToETagTest() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (Stream blobStream = blob.OpenRead()) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - using (Stream blobStream = blob.OpenRead()) - { - long length = blobStream.Length; - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blob.OpenRead(accessCondition), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadLockToETagTestAPM() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginOpenRead( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - result = blob.BeginOpenRead( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenRead(result)) - { - long length = blobStream.Length; - blob.SetMetadata(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadata(); - result = blob.BeginOpenRead( - accessCondition, - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndOpenRead(result), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadLockToETagTestTask() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(wholeBlob).Wait(); - } - - using (Stream blobStream = blob.OpenReadAsync().Result) - { - blobStream.Read(outBuffer, 0, outBuffer.Length); - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - using (Stream blobStream = blob.OpenReadAsync().Result) - { - long length = blobStream.Length; - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedException( - () => blobStream.Read(outBuffer, 0, outBuffer.Length), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - blob.SetMetadataAsync().Wait(); - TestHelper.ExpectedExceptionTask( - blob.OpenReadAsync(accessCondition, null, null), - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - private static int BlobReadStreamSeekAndCompare(Stream blobStream, byte[] bufferToCompare, long offset, int readSize, int expectedReadCount, bool isAsync) - { - byte[] testBuffer = new byte[readSize]; - - if (isAsync) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - IAsyncResult result = blobStream.BeginRead(testBuffer, 0, readSize, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - int readCount = blobStream.EndRead(result); - Assert.AreEqual(expectedReadCount, readCount); - } - } - else - { - int readCount = blobStream.Read(testBuffer, 0, readSize); - Assert.AreEqual(expectedReadCount, readCount); - } - - for (int i = 0; i < expectedReadCount; i++) - { - Assert.AreEqual(bufferToCompare[i + offset], testBuffer[i]); - } - - return expectedReadCount; - } - - private static int BlobReadStreamSeekTest(Stream blobStream, long streamReadSize, byte[] bufferToCompare, bool isAsync) - { - int attempts = 1; - long position = 0; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 1024, isAsync); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 512, 512, isAsync); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-128, SeekOrigin.End); - position = bufferToCompare.Length - 128; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 128, isAsync); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(4096, SeekOrigin.Begin); - position = 4096; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 1024, isAsync); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(4096, SeekOrigin.Current); - position += 4096; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 1024, isAsync); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-4096, SeekOrigin.Current); - position -= 4096; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 128, 128, isAsync); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(streamReadSize + 4096 - 512, SeekOrigin.Begin); - position = streamReadSize + 4096 - 512; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 512, isAsync); - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 1024, isAsync); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-1024, SeekOrigin.Current); - position -= 1024; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 2048, 2048, isAsync); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-128, SeekOrigin.End); - position = bufferToCompare.Length - 128; - Assert.AreEqual(position, blobStream.Position); - position += BlobReadStreamSeekAndCompare(blobStream, bufferToCompare, position, 1024, 128, isAsync); - Assert.AreEqual(position, blobStream.Position); - return attempts; - } - - [TestMethod] - [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobReadStreamSeekTest() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = blob.OpenRead(null, null, opContext)) - { - int attempts = BlobReadStreamSeekTest(blobStream, blob.StreamMinimumReadSizeInBytes, buffer, false); - TestHelper.AssertNAttempts(opContext, attempts); - } - - opContext = new OperationContext(); - using (Stream blobStream = blob.OpenRead(null, null, opContext)) - { - int attempts = BlobReadStreamSeekTest(blobStream, blob.StreamMinimumReadSizeInBytes, buffer, true); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReadStreamSeekTest() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = blob.OpenRead(null, null, opContext)) - { - int attempts = BlobReadStreamSeekTest(blobStream, blob.StreamMinimumReadSizeInBytes, buffer, false); - TestHelper.AssertNAttempts(opContext, attempts); - } - - opContext = new OperationContext(); - using (Stream blobStream = blob.OpenRead(null, null, opContext)) - { - int attempts = BlobReadStreamSeekTest(blobStream, blob.StreamMinimumReadSizeInBytes, buffer, true); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobStreamTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobStreamTests.cs deleted file mode 100644 index f3f787066c29e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobStreamTests.cs +++ /dev/null @@ -1,269 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.IO; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobStreamTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("BlobSeek")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobSeekTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream); - Stream blobStream = blob.OpenRead(); - blobStream.Seek(2048, 0); - byte[] buff = new byte[100]; - int numRead = blobStream.Read(buff, 0, 100); - Assert.AreEqual(numRead, 0); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobOpenWriteTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (CloudBlobStream blobStream = blob.OpenWrite(2048)) - { - blobStream.Write(buffer, 0, 2048); - blobStream.Flush(); - - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - blob.DownloadRangeToStream(dstStream, null, null); - - MemoryStream memStream = new MemoryStream(buffer); - TestHelper.AssertStreamsAreEqual(memStream, dstStream); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobOpenReadTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream); - - Stream dstStream = blob.OpenRead(); - TestHelper.AssertStreamsAreEqual(srcStream, dstStream); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("OpenReadWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobOpenReadWriteTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - Stream blobStream = blob.OpenWrite(2048); - blobStream.Write(buffer, 0, 2048); - blobStream.Close(); - - MemoryStream memoryStream = new MemoryStream(buffer); - Stream dstStream = blob.OpenRead(); - TestHelper.AssertStreamsAreEqual(memoryStream, dstStream); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("OpenWriteSeekRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobOpenWriteSeekReadTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - MemoryStream memoryStream = new MemoryStream(buffer); - Stream blobStream = blob.OpenWrite(2048); - blobStream.Write(buffer, 0, 2048); - - Assert.AreEqual(blobStream.Position, 2048); - - blobStream.Seek(1024, 0); - memoryStream.Seek(1024, 0); - Assert.AreEqual(blobStream.Position, 1024); - - byte[] testBuffer = GetRandomBuffer(1024); - - memoryStream.Write(testBuffer, 0, 1024); - blobStream.Write(testBuffer, 0, 1024); - Assert.AreEqual(blobStream.Position, memoryStream.Position); - - blobStream.Close(); - - Stream dstStream = blob.OpenRead(); - TestHelper.AssertStreamsAreEqual(memoryStream, dstStream); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Read when opened in OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobReadWhenOpenWrite() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - MemoryStream memoryStream = new MemoryStream(buffer); - Stream blobStream = blob.OpenWrite(2048); - blobStream.Write(buffer, 0, 2048); - byte[] testBuffer = new byte[2048]; - TestHelper.ExpectedException(() => blobStream.Read(testBuffer, 0, 2048), - "Try reading from a stream opened for Write"); - - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Write when opened in OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobWriteWhenOpenRead() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream); - Stream blobStream = blob.OpenRead(); - - byte[] testBuffer = new byte[2048]; - TestHelper.ExpectedException(() => blobStream.Write(testBuffer, 0, 2048), - "Try writing to a stream opened for read"); - } - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobTestBase.cs deleted file mode 100644 index df6a680ef6421..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobTestBase.cs +++ /dev/null @@ -1,239 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - public partial class BlobTestBase : TestBase - { - public static void WaitForCopy(ICloudBlob blob) - { - bool copyInProgress = true; - while (copyInProgress) - { - Thread.Sleep(1000); - blob.FetchAttributes(); - copyInProgress = (blob.CopyState.Status == CopyStatus.Pending); - } - } - -#if TASK - public static void WaitForCopyTask(ICloudBlob blob) - { - bool copyInProgress = true; - while (copyInProgress) - { - Thread.Sleep(1000); - blob.FetchAttributesAsync().Wait(); - copyInProgress = (blob.CopyState.Status == CopyStatus.Pending); - } - } -#endif - - public static List CreateBlobs(CloudBlobContainer container, int count, BlobType type) - { - string name; - List blobs = new List(); - for (int i = 0; i < count; i++) - { - switch (type) - { - case BlobType.BlockBlob: - name = "bb" + Guid.NewGuid().ToString(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference(name); - blockBlob.PutBlockList(new string[] { }); - blobs.Add(name); - break; - - case BlobType.PageBlob: - name = "pb" + Guid.NewGuid().ToString(); - CloudPageBlob pageBlob = container.GetPageBlobReference(name); - pageBlob.Create(0); - blobs.Add(name); - break; - } - } - return blobs; - } - -#if TASK - public static List CreateBlobsTask(CloudBlobContainer container, int count, BlobType type) - { - string name; - List blobs = new List(); - for (int i = 0; i < count; i++) - { - switch (type) - { - case BlobType.BlockBlob: - name = "bb" + Guid.NewGuid().ToString(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference(name); - blockBlob.PutBlockListAsync(new string[] { }).Wait(); - blobs.Add(name); - break; - - case BlobType.PageBlob: - name = "pb" + Guid.NewGuid().ToString(); - CloudPageBlob pageBlob = container.GetPageBlobReference(name); - pageBlob.CreateAsync(0).Wait(); - blobs.Add(name); - break; - } - } - return blobs; - } -#endif - - public static void UploadText(ICloudBlob blob, string text, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - byte[] textAsBytes = encoding.GetBytes(text); - using (MemoryStream stream = new MemoryStream()) - { - stream.Write(textAsBytes, 0, textAsBytes.Length); - if (blob.BlobType == BlobType.PageBlob) - { - int lastPageSize = (int)(stream.Length % 512); - if (lastPageSize != 0) - { - byte[] padding = new byte[512 - lastPageSize]; - stream.Write(padding, 0, padding.Length); - } - } - - stream.Seek(0, SeekOrigin.Begin); - blob.ServiceClient.ParallelOperationThreadCount = 2; - blob.UploadFromStream(stream, accessCondition, options, operationContext); - } - } - - public static void UploadTextAPM(ICloudBlob blob, string text, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - byte[] textAsBytes = encoding.GetBytes(text); - using (MemoryStream stream = new MemoryStream()) - { - stream.Write(textAsBytes, 0, textAsBytes.Length); - if (blob.BlobType == BlobType.PageBlob) - { - int lastPageSize = (int)(stream.Length % 512); - if (lastPageSize != 0) - { - byte[] padding = new byte[512 - lastPageSize]; - stream.Write(padding, 0, padding.Length); - } - } - - stream.Seek(0, SeekOrigin.Begin); - blob.ServiceClient.ParallelOperationThreadCount = 2; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginUploadFromStream(stream, accessCondition, options, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - } - } - -#if TASK - public static void UploadTextTask(ICloudBlob blob, string text, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - byte[] textAsBytes = encoding.GetBytes(text); - using (MemoryStream stream = new MemoryStream()) - { - stream.Write(textAsBytes, 0, textAsBytes.Length); - if (blob.BlobType == BlobType.PageBlob) - { - int lastPageSize = (int)(stream.Length % 512); - if (lastPageSize != 0) - { - byte[] padding = new byte[512 - lastPageSize]; - stream.Write(padding, 0, padding.Length); - } - } - - stream.Seek(0, SeekOrigin.Begin); - blob.ServiceClient.ParallelOperationThreadCount = 2; - try - { - blob.UploadFromStreamAsync(stream, accessCondition, options, operationContext).Wait(); - } - catch (AggregateException ex) - { - if (ex.InnerException != null) - { - throw ex.InnerException; - } - - throw; - } - } - } -#endif - - public static string DownloadText(ICloudBlob blob, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (MemoryStream stream = new MemoryStream()) - { - blob.DownloadToStream(stream, accessCondition, options, operationContext); - return encoding.GetString(stream.ToArray()); - } - } - - public static string DownloadTextAPM(ICloudBlob blob, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (MemoryStream stream = new MemoryStream()) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginDownloadToStream(stream, accessCondition, options, operationContext, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - return encoding.GetString(stream.ToArray()); - } - } - } - -#if TASK - public static string DownloadTextTask(ICloudBlob blob, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (MemoryStream stream = new MemoryStream()) - { - try - { - blob.DownloadToStreamAsync(stream, accessCondition, options, operationContext).Wait(); - } - catch (AggregateException ex) - { - if (ex.InnerException != null) - { - throw ex.InnerException; - } - - throw; - } - return encoding.GetString(stream.ToArray()); - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobUploadDownloadTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobUploadDownloadTest.cs deleted file mode 100644 index 55b04d092d927..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobUploadDownloadTest.cs +++ /dev/null @@ -1,1407 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobUploadDownloadTest : BlobTestBase - { - - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - this.testContainer.CreateIfNotExists(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.DeleteIfExists(); - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Download a specific range of the blob to a stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobDownloadToStreamRangeTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(wholeBlob); - - byte[] testBuffer = new byte[1024]; - MemoryStream blobStream = new MemoryStream(testBuffer); - StorageException storageEx = TestHelper.ExpectedException( - () => blob.DownloadRangeToStream(blobStream, 0, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - blob.DownloadRangeToStream(blobStream, 0, 1024); - Assert.AreEqual(blobStream.Position, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream, wholeBlob, 0, 0, 1024); - - CloudPageBlob blob2 = this.testContainer.GetPageBlobReference("blob1"); - MemoryStream blobStream2 = new MemoryStream(testBuffer); - storageEx = TestHelper.ExpectedException( - () => blob2.DownloadRangeToStream(blobStream, 1024, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - blob2.DownloadRangeToStream(blobStream2, 1024, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream2, wholeBlob, 0, 1024, 1024); - - AssertAreEqual(blob, blob2); - } - } - - [TestMethod] - [Description("Upload a stream to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobUploadFromStreamTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream); - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - blob.DownloadRangeToStream(dstStream, null, null); - TestHelper.AssertStreamsAreEqual(srcStream, dstStream); - } - } - - [TestMethod] - [Description("Upload from text to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobUploadWithoutMD5ValidationAndStoreBlobContentTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - BlobRequestOptions options = new BlobRequestOptions(); - options.DisableContentMD5Validation = false; - options.StoreBlobContentMD5 = false; - OperationContext context = new OperationContext(); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream, null, options, context); - blob.FetchAttributes(); - string md5 = blob.Properties.ContentMD5; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.SetProperties(null, options, context); - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - TestHelper.ExpectedException(() => blob.DownloadRangeToStream(dstStream, null, null, null, options, context), - "Try to Download a stream with a corrupted md5 and DisableMD5Validation set to false", - HttpStatusCode.OK); - - options.DisableContentMD5Validation = true; - blob.SetProperties(null, options, context); - byte[] testBuffer2 = new byte[2048]; - MemoryStream dstStream2 = new MemoryStream(testBuffer2); - blob.DownloadRangeToStream(dstStream2, null, null, null, options, context); - } - } - - [TestMethod] - [Description("Upload from text to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobEmptyHeaderSigningTest() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - OperationContext context = new OperationContext(); - try - { - container.Create(null, context); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - context.UserHeaders = new Dictionary(); - context.UserHeaders.Add("x-ms-foo", String.Empty); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - blob.UploadFromStream(srcStream, null, null, context); - } - byte[] testBuffer2 = new byte[2048]; - MemoryStream dstStream2 = new MemoryStream(testBuffer2); - blob.DownloadRangeToStream(dstStream2, null, null, null, null, context); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadDownloadFile() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadDownloadFile(blob, 0, false); - this.DoUploadDownloadFile(blob, 4096, false); - this.DoUploadDownloadFile(blob, 4097, false); - - TestHelper.ExpectedException( - () => blob.UploadFromFile("non_existent.file", FileMode.Open), - "UploadFromFile requires an existing file"); - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadDownloadFile() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadDownloadFile(blob, 0, false); - this.DoUploadDownloadFile(blob, 4096, false); - - TestHelper.ExpectedException( - () => this.DoUploadDownloadFile(blob, 4097, false), - "Page blobs must be 512-byte aligned"); - - TestHelper.ExpectedException( - () => blob.UploadFromFile("non_existent.file", FileMode.Open), - "UploadFromFile requires an existing file"); - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadDownloadFileAPM() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadDownloadFile(blob, 0, true); - this.DoUploadDownloadFile(blob, 4096, true); - this.DoUploadDownloadFile(blob, 4097, true); - - TestHelper.ExpectedException( - () => blob.BeginUploadFromFile("non_existent.file", FileMode.Open, null, null), - "UploadFromFile requires an existing file"); - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadDownloadFileAPM() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadDownloadFile(blob, 0, true); - this.DoUploadDownloadFile(blob, 4096, true); - - TestHelper.ExpectedException( - () => this.DoUploadDownloadFile(blob, 4097, true), - "Page blobs must be 512-byte aligned"); - - TestHelper.ExpectedException( - () => blob.BeginUploadFromFile("non_existent.file", FileMode.Open, null, null), - "UploadFromFile requires an existing file"); - } - -#if TASK - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadDownloadFileTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadDownloadFileTask(blob, 0); - this.DoUploadDownloadFileTask(blob, 4096); - this.DoUploadDownloadFileTask(blob, 4097); - - TestHelper.ExpectedException( - () => blob.UploadFromFileAsync("non_existent.file", FileMode.Open), - "UploadFromFile requires an existing file"); - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadDownloadFileTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadDownloadFileTask(blob, 0); - this.DoUploadDownloadFileTask(blob, 4096); - - TestHelper.ExpectedException( - () => this.DoUploadDownloadFileTask(blob, 4097), - "Page blobs must be 512-byte aligned"); - - TestHelper.ExpectedException( - () => blob.UploadFromFileAsync("non_existent.file", FileMode.Open), - "UploadFromFile requires an existing file"); - } - - private void DoUploadDownloadFileTask(ICloudBlob blob, int fileSize) - { - string inputFileName = Path.GetTempFileName(); - string outputFileName = Path.GetTempFileName(); - - try - { - byte[] buffer = GetRandomBuffer(fileSize); - using (FileStream file = new FileStream(inputFileName, FileMode.Create, FileAccess.Write)) - { - file.Write(buffer, 0, buffer.Length); - } - - blob.UploadFromFileAsync(inputFileName, FileMode.Open).Wait(); - - OperationContext context = new OperationContext(); - blob.UploadFromFileAsync(inputFileName, FileMode.Open, null, null, context).Wait(); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - TestHelper.ExpectedException( - () => blob.DownloadToFileAsync(outputFileName, FileMode.CreateNew), - "CreateNew on an existing file should fail"); - - context = new OperationContext(); - blob.DownloadToFileAsync(outputFileName, FileMode.Create, null, null, context).Wait(); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - using ( - FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - TestHelper.AssertStreamsAreEqual(inputFileStream, outputFileStream); - } - - blob.DownloadToFileAsync(outputFileName, FileMode.Append).Wait(); - - using ( - FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - Assert.AreEqual(2 * fileSize, outputFileStream.Length); - - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - - inputFileStream.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - } - } - catch (AggregateException ex) - { - if (ex.InnerException != null) - { - throw ex.InnerException; - } - - throw; - } - finally - { - File.Delete(inputFileName); - File.Delete(outputFileName); - } - } -#endif - - private void DoUploadDownloadFile(ICloudBlob blob, int fileSize, bool isAsync) - { - string inputFileName = Path.GetTempFileName(); - string outputFileName = Path.GetTempFileName(); - - try - { - byte[] buffer = GetRandomBuffer(fileSize); - using (FileStream file = new FileStream(inputFileName, FileMode.Create, FileAccess.Write)) - { - file.Write(buffer, 0, buffer.Length); - } - - if (isAsync) - { - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginUploadFromFile(inputFileName, FileMode.Open, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromFile(result); - - OperationContext context = new OperationContext(); - result = blob.BeginUploadFromFile(inputFileName, FileMode.Open, null, null, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromFile(result); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - TestHelper.ExpectedException( - () => blob.BeginDownloadToFile(outputFileName, FileMode.CreateNew, null, null), - "CreateNew on an existing file should fail"); - - context = new OperationContext(); - result = blob.BeginDownloadToFile(outputFileName, FileMode.Create, null, null, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToFile(result); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - using (FileStream inputFile = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFile = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - TestHelper.AssertStreamsAreEqual(inputFile, outputFile); - } - - result = blob.BeginDownloadToFile(outputFileName, FileMode.Append, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToFile(result); - - using (FileStream inputFile = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFile = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - Assert.AreEqual(2 * fileSize, outputFile.Length); - - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFile.ReadByte(), outputFile.ReadByte()); - } - - inputFile.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFile.ReadByte(), outputFile.ReadByte()); - } - } - } - } - else - { - blob.UploadFromFile(inputFileName, FileMode.Open); - - OperationContext context = new OperationContext(); - blob.UploadFromFile(inputFileName, FileMode.Open, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - TestHelper.ExpectedException( - () => blob.DownloadToFile(outputFileName, FileMode.CreateNew), - "CreateNew on an existing file should fail"); - - context = new OperationContext(); - blob.DownloadToFile(outputFileName, FileMode.Create, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - using (FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - TestHelper.AssertStreamsAreEqual(inputFileStream, outputFileStream); - } - - blob.DownloadToFile(outputFileName, FileMode.Append); - - using (FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - Assert.AreEqual(2 * fileSize, outputFileStream.Length); - - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - - inputFileStream.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - } - } - } - finally - { - File.Delete(inputFileName); - File.Delete(outputFileName); - } - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromByteArray() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 2 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 1 * 512, 2 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 2 * 512, 2 * 512, false); - this.DoUploadFromByteArrayTest(blob, 512, 0, 511, false); - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromByteArrayAPM() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 2 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 1 * 512, 2 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 2 * 512, 2 * 512, true); - this.DoUploadFromByteArrayTest(blob, 512, 0, 511, true); - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromByteArray() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 2 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 1 * 512, 2 * 512, false); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 2 * 512, 2 * 512, false); - - TestHelper.ExpectedException( - () => this.DoUploadFromByteArrayTest(blob, 512, 0, 511, false), - "Page blobs must be 512-byte aligned"); - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromByteArrayAPM() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 4 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 0, 2 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 1 * 512, 2 * 512, true); - this.DoUploadFromByteArrayTest(blob, 4 * 512, 2 * 512, 2 * 512, true); - - TestHelper.ExpectedException( - () => this.DoUploadFromByteArrayTest(blob, 512, 0, 511, true), - "Page blobs must be 512-byte aligned"); - } - -#if TASK - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromByteArrayTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 0, 4 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 0, 2 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 1 * 512, 2 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 2 * 512, 2 * 512); - this.DoUploadFromByteArrayTestTask(blob, 512, 0, 511); - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromByteArrayTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 0, 4 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 0, 2 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 1 * 512, 2 * 512); - this.DoUploadFromByteArrayTestTask(blob, 4 * 512, 2 * 512, 2 * 512); - - TestHelper.ExpectedException( - () => this.DoUploadFromByteArrayTestTask(blob, 512, 0, 511), - "Page blobs must be 512-byte aligned"); - } - - private void DoUploadFromByteArrayTestTask(ICloudBlob blob, int bufferSize, int bufferOffset, int count) - { - byte[] buffer = GetRandomBuffer(bufferSize); - byte[] downloadedBuffer = new byte[bufferSize]; - int downloadLength; - - try - { - blob.UploadFromByteArrayAsync(buffer, bufferOffset, count).Wait(); - downloadLength = blob.DownloadToByteArrayAsync(downloadedBuffer, 0).Result; - } - catch (AggregateException ex) - { - if (ex.InnerException != null) - { - throw ex.InnerException; - } - - throw; - } - - Assert.AreEqual(count, downloadLength); - - for (int i = 0; i < count; i++) - { - Assert.AreEqual(buffer[i + bufferOffset], downloadedBuffer[i]); - } - } -#endif - - private void DoUploadFromByteArrayTest(ICloudBlob blob, int bufferSize, int bufferOffset, int count, bool isAsync) - { - byte[] buffer = GetRandomBuffer(bufferSize); - byte[] downloadedBuffer = new byte[bufferSize]; - int downloadLength; - - if (isAsync) - { - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginUploadFromByteArray(buffer, bufferOffset, count, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromByteArray(result); - - result = blob.BeginDownloadToByteArray(downloadedBuffer, 0, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - downloadLength = blob.EndDownloadToByteArray(result); - } - } - else - { - blob.UploadFromByteArray(buffer, bufferOffset, count); - downloadLength = blob.DownloadToByteArray(downloadedBuffer, 0); - } - - Assert.AreEqual(count, downloadLength); - - for (int i = 0; i < count; i++) - { - Assert.AreEqual(buffer[i + bufferOffset], downloadedBuffer[i]); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToByteArray() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 0); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 0); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 0); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToByteArrayAPM() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 1); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 1); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 1); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToByteArrayAPMOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 2); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 2); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 2); - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToByteArrayTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 0, false); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 1 * 512, false); - this.DoDownloadToByteArrayTestTask(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToByteArrayOverloadTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 0, true); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 1 * 512, true); - this.DoDownloadToByteArrayTestTask(blob, 2 * 512, 4 * 512, 1 * 512, true); - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToByteArray() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 0); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 0); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 0); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToByteArrayAPM() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 1); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 1); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 1); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToByteArrayAPMOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 0, 2); - this.DoDownloadToByteArrayTest(blob, 1 * 512, 2 * 512, 1 * 512, 2); - this.DoDownloadToByteArrayTest(blob, 2 * 512, 4 * 512, 1 * 512, 2); - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToByteArrayTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 0, false); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 1 * 512, false); - this.DoDownloadToByteArrayTestTask(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToByteArrayOverloadTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 0, true); - this.DoDownloadToByteArrayTestTask(blob, 1 * 512, 2 * 512, 1 * 512, true); - this.DoDownloadToByteArrayTestTask(blob, 2 * 512, 4 * 512, 1 * 512, true); - } -#endif - - /// - /// Single put blob and get blob - /// - /// The blob size. - /// The blob offset. - /// 0 - Sunc, 1 - APM and 2 - APM overload. - private void DoDownloadToByteArrayTest(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, int option) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (option == 0) - { - blob.UploadFromStream(originalBlob); - downloadLength = blob.DownloadToByteArray(resultBuffer, bufferOffset); - } - else if (option == 1) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - result = blob.BeginDownloadToByteArray(resultBuffer, - bufferOffset, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - downloadLength = blob.EndDownloadToByteArray(result); - } - } - else - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - OperationContext context = new OperationContext(); - result = blob.BeginDownloadToByteArray(resultBuffer, - bufferOffset, /* offset */ - null, /* accessCondition */ - null, /* options */ - context, /* operationContext */ - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - downloadLength = blob.EndDownloadToByteArray(result); - } - } - - int downloadSize = Math.Min(blobSize, bufferSize - bufferOffset); - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < blob.Properties.Length; i++) - { - Assert.AreEqual(buffer[i], resultBuffer[bufferOffset + i]); - } - - for (int j = 0; j < bufferOffset; j++) - { - Assert.AreEqual(0, resultBuffer2[j]); - } - - if (bufferOffset + blobSize < bufferSize) - { - for (int k = bufferOffset + blobSize; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer2[k]); - } - } - } - } - -#if TASK - /// - /// Single put blob and get blob - /// - /// The blob size. - /// The blob offset. - /// Run with overloaded parameters. - private void DoDownloadToByteArrayTestTask(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, bool overload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(originalBlob).Wait(); - - if (overload) - { - downloadLength = blob.DownloadToByteArrayAsync( - resultBuffer, - bufferOffset, - null, - null, - new OperationContext()) - .Result; - } - else - { - downloadLength = blob.DownloadToByteArrayAsync(resultBuffer, bufferOffset).Result; - } - - int downloadSize = Math.Min(blobSize, bufferSize - bufferOffset); - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < blob.Properties.Length; i++) - { - Assert.AreEqual(buffer[i], resultBuffer[bufferOffset + i]); - } - - for (int j = 0; j < bufferOffset; j++) - { - Assert.AreEqual(0, resultBuffer2[j]); - } - - if (bufferOffset + blobSize < bufferSize) - { - for (int k = bufferOffset + blobSize; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer2[k]); - } - } - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArray() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 0); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 0); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArrayAPM() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 1); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 1); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArrayAPMOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 2); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 2); - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArrayTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 1023, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 0, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 512, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArrayOverloadTask() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 1023, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 0, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 512, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 0, 512, true); - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArray() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 0); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 0); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 0); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 0); - - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArrayAPM() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 1); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 1); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 1); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 1); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArrayAPMOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, null, null, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, 2); - this.DoDownloadRangeToByteArray(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, 2); - - // Edge cases - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 1023, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 0, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 0, 512, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 1023, 1, 2); - this.DoDownloadRangeToByteArray(blob, 1024, 1024, 512, 0, 512, 2); - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArrayTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 1023, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 0, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 512, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 1023, 1, false); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArrayOverloadTask() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - this.DoDownloadRangeToByteArrayTask(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 1023, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 0, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 0, 512, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 1023, 1, true); - this.DoDownloadRangeToByteArrayTask(blob, 1024, 1024, 512, 0, 512, true); - } -#endif - - /// - /// Single put blob and get blob - /// - /// The blob size. - /// The output buffer size. - /// The output buffer offset. - /// The blob offset. - /// Length of the data range to download. - /// 0 - Sync, 1 - APM and 2 - APM overload. - private void DoDownloadRangeToByteArray(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, long? blobOffset, long? length, int option) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (option == 0) - { - blob.UploadFromStream(originalBlob); - downloadLength = blob.DownloadRangeToByteArray(resultBuffer, bufferOffset, blobOffset, length); - } - else if (option == 1) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - result = blob.BeginDownloadRangeToByteArray(resultBuffer, - bufferOffset, - blobOffset, - length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - downloadLength = blob.EndDownloadRangeToByteArray(result); - } - } - else - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - OperationContext context = new OperationContext(); - result = blob.BeginDownloadRangeToByteArray(resultBuffer, - bufferOffset, - blobOffset, - length, - null, - null, - context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - downloadLength = blob.EndDownloadRangeToByteArray(result); - } - } - - int downloadSize = Math.Min(blobSize - (int)(blobOffset.HasValue ? blobOffset.Value : 0), bufferSize - bufferOffset); - if (length.HasValue && (length.Value < downloadSize)) - { - downloadSize = (int)length.Value; - } - - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < bufferOffset; i++) - { - Assert.AreEqual(0, resultBuffer[i]); - } - - for (int j = 0; j < downloadLength; j++) - { - Assert.AreEqual(buffer[(blobOffset.HasValue ? blobOffset.Value : 0) + j], resultBuffer[bufferOffset + j]); - } - - for (int k = bufferOffset + downloadLength; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer[k]); - } - } - } - -#if TASK - /// - /// Single put blob and get blob - /// - /// The blob size. - /// The output buffer size. - /// The output buffer offset. - /// The blob offset. - /// Length of the data range to download. - /// Run with overloaded parameters. - private void DoDownloadRangeToByteArrayTask(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, long? blobOffset, long? length, bool overload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (overload) - { - blob.UploadFromStream(originalBlob); - downloadLength = blob.DownloadRangeToByteArrayAsync( - resultBuffer, bufferOffset, blobOffset, length, null, null, new OperationContext()).Result; - } - else - { - blob.UploadFromStream(originalBlob); - downloadLength = blob.DownloadRangeToByteArrayAsync(resultBuffer, bufferOffset, blobOffset, length).Result; - } - - int downloadSize = Math.Min(blobSize - (int)(blobOffset.HasValue ? blobOffset.Value : 0), bufferSize - bufferOffset); - if (length.HasValue && (length.Value < downloadSize)) - { - downloadSize = (int)length.Value; - } - - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < bufferOffset; i++) - { - Assert.AreEqual(0, resultBuffer[i]); - } - - for (int j = 0; j < downloadLength; j++) - { - Assert.AreEqual(buffer[(blobOffset.HasValue ? blobOffset.Value : 0) + j], resultBuffer[bufferOffset + j]); - } - - for (int k = bufferOffset + downloadLength; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer[k]); - } - } - } -#endif - - #region Negative tests - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadRangeToByteArrayNegativeTests() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - this.DoDownloadRangeToByteArrayNegativeTests(blob); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadRangeToByteArrayNegativeTests() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - this.DoDownloadRangeToByteArrayNegativeTests(blob); - } - - private void DoDownloadRangeToByteArrayNegativeTests(ICloudBlob blob) - { - int blobLength = 1024; - int resultBufSize = 1024; - byte[] buffer = GetRandomBuffer(blobLength); - byte[] resultBuffer = new byte[resultBufSize]; - - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.UploadFromStream(stream); - - TestHelper.ExpectedException(() => blob.DownloadRangeToByteArray(resultBuffer, 0, 1024, 1), "Try invalid length", HttpStatusCode.RequestedRangeNotSatisfiable); - StorageException ex = TestHelper.ExpectedException(() => blob.DownloadToByteArray(resultBuffer, 1024), "Provide invalid offset"); - Assert.IsInstanceOfType(ex.InnerException, typeof(NotSupportedException)); - ex = TestHelper.ExpectedException(() => blob.DownloadRangeToByteArray(resultBuffer, 1023, 0, 2), "Should fail when offset + length required is greater than size of the buffer"); - Assert.IsInstanceOfType(ex.InnerException, typeof(NotSupportedException)); - ex = TestHelper.ExpectedException(() => blob.DownloadRangeToByteArray(resultBuffer, 0, 0, -10), "Fail when a negative length is specified"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - TestHelper.ExpectedException(() => blob.DownloadRangeToByteArray(resultBuffer, -10, 0, 20), "Fail if a negative offset is provided"); - ex = TestHelper.ExpectedException(() => blob.DownloadRangeToByteArray(resultBuffer, 0, -10, 20), "Fail if a negative blob offset is provided"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - } - } - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobWriteStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobWriteStreamTest.cs deleted file mode 100644 index b6fa63e90fc8b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/BlobWriteStreamTest.cs +++ /dev/null @@ -1,1667 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Security.Cryptography; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobWriteStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create blobs using blob stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobWriteStreamOpenAndClose() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream blobStream = blockBlob.OpenWrite()) - { - } - - CloudBlockBlob blockBlob2 = container.GetBlockBlobReference("blob1"); - blockBlob2.FetchAttributes(); - Assert.AreEqual(0, blockBlob2.Properties.Length); - Assert.AreEqual(BlobType.BlockBlob, blockBlob2.Properties.BlobType); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - TestHelper.ExpectedException( - () => pageBlob.OpenWrite(null), - "Opening a page blob stream with no size should fail on a blob that does not exist", - HttpStatusCode.NotFound); - using (Stream blobStream = pageBlob.OpenWrite(1024)) - { - } - using (Stream blobStream = pageBlob.OpenWrite(null)) - { - } - - CloudPageBlob pageBlob2 = container.GetPageBlobReference("blob2"); - pageBlob2.FetchAttributes(); - Assert.AreEqual(1024, pageBlob2.Properties.Length); - Assert.AreEqual(BlobType.PageBlob, pageBlob2.Properties.BlobType); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamOpenWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudBlockBlob existingBlob = container.GetBlockBlobReference("blob"); - existingBlob.PutBlockList(new List()); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedException( - () => blob.OpenWrite(accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotFound); - - blob = container.GetBlockBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = blob.OpenWrite(accessCondition); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = blob.OpenWrite(accessCondition); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = blob.OpenWrite(accessCondition); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = blob.OpenWrite(accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = existingBlob.OpenWrite(accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = existingBlob.OpenWrite(accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = existingBlob.OpenWrite(accessCondition); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = existingBlob.OpenWrite(accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = existingBlob.OpenWrite(accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = existingBlob.OpenWrite(accessCondition); - existingBlob.SetProperties(); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetBlockBlobReference("blob7"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = blob.OpenWrite(accessCondition); - blob.PutBlockList(new List()); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - blob = container.GetBlockBlobReference("blob8"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value); - blobStream = existingBlob.OpenWrite(accessCondition); - - // Wait 1 second so that the last modified time of the blob is in the past - Thread.Sleep(TimeSpan.FromSeconds(1)); - - existingBlob.SetProperties(); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamOpenAPMWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudBlockBlob existingBlob = container.GetBlockBlobReference("blob"); - existingBlob.PutBlockList(new List()); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - IAsyncResult result = blob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotFound); - - blob = container.GetBlockBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - result = blob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Stream blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - result = blob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = blob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = blob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - existingBlob.SetProperties(); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetBlockBlobReference("blob7"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blob.PutBlockList(new List()); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - blob = container.GetBlockBlobReference("blob8"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value); - result = existingBlob.BeginOpenWrite(accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - - // Wait 1 second so that the last modified time of the blob is in the past - Thread.Sleep(TimeSpan.FromSeconds(1)); - - existingBlob.SetProperties(); - TestHelper.ExpectedException( - () => blobStream.Dispose(), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamOpenWithAccessConditionTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - - try - { - CloudBlockBlob existingBlob = container.GetBlockBlobReference("blob"); - existingBlob.PutBlockListAsync(new List()).Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedExceptionTask( - blob.OpenWriteAsync(accessCondition, null, null), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.NotFound); - - blob = container.GetBlockBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = blob.OpenWriteAsync(accessCondition, null ,null).Result; - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = blob.OpenWriteAsync(accessCondition, null, null).Result; - blobStream.Dispose(); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamOpenWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudPageBlob existingBlob = container.GetPageBlobReference("blob"); - existingBlob.Create(1024); - - CloudPageBlob blob = container.GetPageBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedException( - () => blob.OpenWrite(1024, accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetPageBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = blob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = blob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = blob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = blob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = existingBlob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(1024, accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = existingBlob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(1024, accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(1024, accessCondition), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = existingBlob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(1024, accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = existingBlob.OpenWrite(1024, accessCondition); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - TestHelper.ExpectedException( - () => existingBlob.OpenWrite(1024, accessCondition), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamOpenAPMWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudPageBlob existingBlob = container.GetPageBlobReference("blob"); - existingBlob.Create(1024); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob = container.GetPageBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - IAsyncResult result = blob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetPageBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - result = blob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Stream blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - result = blob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = blob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = blob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = blob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream = existingBlob.EndOpenWrite(result); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - result = existingBlob.BeginOpenWrite(1024, accessCondition, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => existingBlob.EndOpenWrite(result), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamOpenWithAccessConditionTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - - try - { - CloudPageBlob existingBlob = container.GetPageBlobReference("blob"); - existingBlob.CreateAsync(1024).Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - TestHelper.ExpectedExceptionTask( - blob.OpenWriteAsync(1024, accessCondition, null, null), - "OpenWrite with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetPageBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = blob.OpenWriteAsync(1024, accessCondition, null, null).Result; - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = blob.OpenWriteAsync(1024, accessCondition, null, null).Result; - blobStream.Dispose(); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamBasicTest() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - MD5 hasher = MD5.Create(); - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - using (Stream blobStream = blob.OpenWrite(null, options)) - { - for (int i = 0; i < 3; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamOneByteTest() - { - byte buffer = 127; - - MD5 hasher = MD5.Create(); - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 16 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - using (Stream blobStream = blob.OpenWrite(null, options)) - { - for (int i = 0; i < 1 * 1024 * 1024; i++) - { - blobStream.WriteByte(buffer); - wholeBlob.WriteByte(buffer); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamBasicTestAPM() - { - byte[] buffer = GetRandomBuffer(1024 * 1024); - - MD5 hasher = MD5.Create(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.ParallelOperationThreadCount = 4; - string name = GetRandomContainerName(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = buffer.Length; - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - using (CloudBlobStream blobStream = blob.OpenWrite(null, options)) - { - IAsyncResult[] results = new IAsyncResult[blobClient.ParallelOperationThreadCount * 2]; - for (int i = 0; i < results.Length; i++) - { - results[i] = blobStream.BeginWrite(buffer, 0, buffer.Length, null, null); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - for (int i = 0; i < blobClient.ParallelOperationThreadCount; i++) - { - Assert.IsTrue(results[i].IsCompleted); - } - - for (int i = blobClient.ParallelOperationThreadCount; i < results.Length; i++) - { - Assert.IsFalse(results[i].IsCompleted); - } - - for (int i = 0; i < results.Length; i++) - { - blobStream.EndWrite(results[i]); - } - - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - IAsyncResult result = blobStream.BeginCommit( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndCommit(result); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Seek in a blob write stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamSeekTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream blobStream = blob.OpenWrite()) - { - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Block blob write stream should not be seekable"); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamFlushTest() - { - byte[] buffer = GetRandomBuffer(512 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = blob.OpenWrite(null, null, opContext)) - { - for (int i = 0; i < 3; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - } - - Assert.AreEqual(1, opContext.RequestResults.Count); - - blobStream.Flush(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - blobStream.Flush(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - blobStream.Commit(); - - Assert.AreEqual(4, opContext.RequestResults.Count); - } - - Assert.AreEqual(4, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobWriteStreamFlushTestAPM() - { - byte[] buffer = GetRandomBuffer(512 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = blob.OpenWrite(null, null, opContext)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - for (int i = 0; i < 3; i++) - { - result = blobStream.BeginWrite( - buffer, - 0, - buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndWrite(result); - wholeBlob.Write(buffer, 0, buffer.Length); - } - - Assert.AreEqual(1, opContext.RequestResults.Count); - - ICancellableAsyncResult cancellableResult = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsFalse(cancellableResult.IsCompleted); - cancellableResult.Cancel(); - waitHandle.WaitOne(); - blobStream.EndFlush(cancellableResult); - - result = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsFalse(result.IsCompleted); - TestHelper.ExpectedException( - () => blobStream.BeginFlush(null, null), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blobStream.BeginFlush(null, null), - null); - blobStream.EndFlush(result); - Assert.IsFalse(result.CompletedSynchronously); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - result = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsTrue(result.CompletedSynchronously); - waitHandle.WaitOne(); - blobStream.EndFlush(result); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - result = blobStream.BeginWrite( - buffer, - 0, - buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndWrite(result); - wholeBlob.Write(buffer, 0, buffer.Length); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - cancellableResult = blobStream.BeginFlush(null, null); - Assert.IsFalse(cancellableResult.IsCompleted); - blobStream.EndFlush(cancellableResult); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - result = blobStream.BeginWrite( - buffer, - 0, - buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndWrite(result); - wholeBlob.Write(buffer, 0, buffer.Length); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - result = blobStream.BeginCommit( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndCommit(result); - - Assert.AreEqual(5, opContext.RequestResults.Count); - } - } - - Assert.AreEqual(5, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamBasicTest() - { - byte[] buffer = GetRandomBuffer(6 * 512); - - MD5 hasher = MD5.Create(); - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 8 * 512; - - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - using (Stream blobStream = blob.OpenWrite(buffer.Length * 3, null, options)) - { - for (int i = 0; i < 3; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - - TestHelper.ExpectedException( - () => blob.OpenWrite(null, null, options), - "OpenWrite with StoreBlobContentMD5 on an existing page blob should fail"); - - using (Stream blobStream = blob.OpenWrite(null)) - { - blobStream.Seek(buffer.Length / 2, SeekOrigin.Begin); - wholeBlob.Seek(buffer.Length / 2, SeekOrigin.Begin); - - for (int i = 0; i < 2; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - wholeBlob.Seek(0, SeekOrigin.End); - } - - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - options.DisableContentMD5Validation = true; - blob.DownloadToStream(downloadedBlob, null, options); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamOneByteTest() - { - byte buffer = 127; - - MD5 hasher = MD5.Create(); - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 16 * 1024; - - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - using (Stream blobStream = blob.OpenWrite(1 * 1024 * 1024, null, options)) - { - for (int i = 0; i < 1 * 1024 * 1024; i++) - { - blobStream.WriteByte(buffer); - wholeBlob.WriteByte(buffer); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamBasicTestAPM() - { - byte[] buffer = GetRandomBuffer(2 * 1024 * 1024); - - MD5 hasher = MD5.Create(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.ParallelOperationThreadCount = 4; - string name = GetRandomContainerName(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = buffer.Length; - - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginOpenWrite(blobClient.ParallelOperationThreadCount * 2 * buffer.Length, null, options, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (CloudBlobStream blobStream = blob.EndOpenWrite(result)) - { - IAsyncResult[] results = new IAsyncResult[blobClient.ParallelOperationThreadCount * 2]; - for (int i = 0; i < results.Length; i++) - { - results[i] = blobStream.BeginWrite(buffer, 0, buffer.Length, null, null); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - for (int i = 0; i < blobClient.ParallelOperationThreadCount; i++) - { - Assert.IsTrue(results[i].IsCompleted); - } - - for (int i = blobClient.ParallelOperationThreadCount; i < results.Length; i++) - { - Assert.IsFalse(results[i].IsCompleted); - } - - for (int i = 0; i < results.Length; i++) - { - blobStream.EndWrite(results[i]); - } - - result = blobStream.BeginCommit( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndCommit(result); - } - } - - wholeBlob.Seek(0, SeekOrigin.Begin); - string md5 = Convert.ToBase64String(hasher.ComputeHash(wholeBlob)); - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - - blobClient.ParallelOperationThreadCount = 2; - - TestHelper.ExpectedException( - () => blob.BeginOpenWrite(null, null, options, null, null, null), - "BeginOpenWrite with StoreBlobContentMD5 on an existing page blob should fail"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginOpenWrite(null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blob.EndOpenWrite(result)) - { - blobStream.Seek(buffer.Length / 2, SeekOrigin.Begin); - wholeBlob.Seek(buffer.Length / 2, SeekOrigin.Begin); - - IAsyncResult[] results = new IAsyncResult[blobClient.ParallelOperationThreadCount * 2]; - for (int i = 0; i < results.Length; i++) - { - results[i] = blobStream.BeginWrite(buffer, 0, buffer.Length, null, null); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - for (int i = 0; i < blobClient.ParallelOperationThreadCount; i++) - { - Assert.IsTrue(results[i].IsCompleted); - } - - for (int i = blobClient.ParallelOperationThreadCount; i < results.Length; i++) - { - Assert.IsFalse(results[i].IsCompleted); - } - - for (int i = 0; i < results.Length; i++) - { - blobStream.EndWrite(results[i]); - } - - wholeBlob.Seek(0, SeekOrigin.End); - } - - blob.FetchAttributes(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - options.DisableContentMD5Validation = true; - blob.DownloadToStream(downloadedBlob, null, options); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Seek in a blob write stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamRandomSeekTest() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - using (Stream blobStream = blob.OpenWrite(buffer.Length)) - { - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Page blob stream should not allow unaligned seeks"); - - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Random random = new Random(); - for (int i = 0; i < 10; i++) - { - int offset = random.Next(buffer.Length / 512) * 512; - SeekRandomly(blobStream, offset); - blobStream.Write(buffer, 0, buffer.Length - offset); - wholeBlob.Seek(offset, SeekOrigin.Begin); - wholeBlob.Write(buffer, 0, buffer.Length - offset); - } - } - - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamFlushTest() - { - byte[] buffer = GetRandomBuffer(512); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() { StoreBlobContentMD5 = true }; - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = blob.OpenWrite(4 * 512, null, options, opContext)) - { - for (int i = 0; i < 3; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - } - - Assert.AreEqual(2, opContext.RequestResults.Count); - - blobStream.Flush(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - blobStream.Flush(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - blobStream.Commit(); - - Assert.AreEqual(5, opContext.RequestResults.Count); - } - - Assert.AreEqual(5, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobWriteStreamFlushTestAPM() - { - byte[] buffer = GetRandomBuffer(512 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() { StoreBlobContentMD5 = true }; - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = blob.OpenWrite(4 * buffer.Length, null, options, opContext)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - for (int i = 0; i < 3; i++) - { - result = blobStream.BeginWrite( - buffer, - 0, - buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndWrite(result); - wholeBlob.Write(buffer, 0, buffer.Length); - } - - Assert.AreEqual(2, opContext.RequestResults.Count); - - ICancellableAsyncResult cancellableResult = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsFalse(cancellableResult.IsCompleted); - cancellableResult.Cancel(); - waitHandle.WaitOne(); - blobStream.EndFlush(cancellableResult); - - result = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsFalse(result.IsCompleted); - TestHelper.ExpectedException( - () => blobStream.BeginFlush(null, null), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blobStream.BeginFlush(null, null), - null); - blobStream.EndFlush(result); - Assert.IsFalse(result.CompletedSynchronously); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - result = blobStream.BeginFlush( - ar => waitHandle.Set(), - null); - Assert.IsTrue(result.CompletedSynchronously); - waitHandle.WaitOne(); - blobStream.EndFlush(result); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - result = blobStream.BeginWrite( - buffer, - 0, - buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndWrite(result); - wholeBlob.Write(buffer, 0, buffer.Length); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - result = blobStream.BeginCommit( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blobStream.EndCommit(result); - - Assert.AreEqual(5, opContext.RequestResults.Count); - } - } - - Assert.AreEqual(5, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobClientTest.cs deleted file mode 100644 index 181c582a726b4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobClientTest.cs +++ /dev/null @@ -1,1630 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobClientTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientConstructor() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - Assert.IsTrue(blobClient.BaseUri.ToString().Contains(TestBase.TargetTenantConfig.BlobServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, blobClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, blobClient.AuthenticationScheme); - } - - [TestMethod] - [Description("Create a service client with uppercase account name")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientWithUppercaseAccountName() - { - StorageCredentials credentials = new StorageCredentials(TestBase.StorageCredentials.AccountName.ToUpper(), TestBase.StorageCredentials.ExportKey()); - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient blobClient = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - container.Exists(); - } - - [TestMethod] - [Description("Compare service client properties of blob objects")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientObjects() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - Assert.AreEqual(blobClient, container.ServiceClient); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blockblob"); - Assert.AreEqual(blobClient, blockBlob.ServiceClient); - CloudPageBlob pageBlob = container.GetPageBlobReference("pageblob"); - Assert.AreEqual(blobClient, pageBlob.ServiceClient); - - CloudBlobContainer container2 = GetRandomContainerReference(); - Assert.AreNotEqual(blobClient, container2.ServiceClient); - CloudBlockBlob blockBlob2 = container2.GetBlockBlobReference("blockblob"); - Assert.AreEqual(container2.ServiceClient, blockBlob2.ServiceClient); - CloudPageBlob pageBlob2 = container2.GetPageBlobReference("pageblob"); - Assert.AreEqual(container2.ServiceClient, pageBlob2.ServiceClient); - } - - [TestMethod] - [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsWithPrefix() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - rootContainer.CreateIfNotExists(); - container.Create(); - - List blobNames = CreateBlobs(container, 3, BlobType.BlockBlob); - List rootBlobNames = CreateBlobs(rootContainer, 2, BlobType.BlockBlob); - - IEnumerable results = blobClient.ListBlobs("bb"); - foreach (CloudBlockBlob blob in results) - { - blob.Delete(); - rootBlobNames.Remove(blob.Name); - } - Assert.AreEqual(0, rootBlobNames.Count); - Assert.AreEqual(0, blobClient.ListBlobs("bb").Count()); - - Assert.AreEqual(0, blobClient.ListBlobs(name).Count()); - results = blobClient.ListBlobs(name + "/"); - foreach (CloudBlockBlob blob in results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedWithPrefix() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - rootContainer.CreateIfNotExists(); - container.Create(); - - List blobNames = CreateBlobs(container, 3, BlobType.BlockBlob); - List rootBlobNames = CreateBlobs(rootContainer, 2, BlobType.BlockBlob); - - BlobResultSegment results; - BlobContinuationToken token = null; - do - { - results = blobClient.ListBlobsSegmented("bb", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - blob.Delete(); - rootBlobNames.Remove(blob.Name); - } - } - while (token != null); - Assert.AreEqual(0, rootBlobNames.Count); - - results = blobClient.ListBlobsSegmented("bb", token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - results = blobClient.ListBlobsSegmented(name, token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - token = null; - do - { - results = blobClient.ListBlobsSegmented(name + "/", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs with empty prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedWithEmptyPrefix() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - rootContainer.CreateIfNotExists(); - container.Create(); - List preExistingBlobs = rootContainer.ListBlobs().Select(b => b.Uri).ToList(); - - List blobNames = CreateBlobs(container, 3, BlobType.BlockBlob); - List rootBlobNames = CreateBlobs(rootContainer, 2, BlobType.BlockBlob); - - BlobResultSegment results; - BlobContinuationToken token = null; - List listedBlobs = new List(); - do - { - results = blobClient.ListBlobsSegmented("", token); - token = results.ContinuationToken; - - foreach (IListBlobItem blob in results.Results) - { - if (preExistingBlobs.Contains(blob.Uri)) - { - continue; - } - else - { - if (blob is CloudPageBlob) - { - ((CloudPageBlob)blob).Delete(); - } - else - { - ((CloudBlockBlob)blob).Delete(); - } - - listedBlobs.Add(blob.Uri); - } - } - } - while (token != null); - - Assert.AreEqual(2, listedBlobs.Count); - do - { - results = container.ListBlobsSegmented("", false, BlobListingDetails.None, null, token, null, null); - token = results.ContinuationToken; - - foreach (IListBlobItem blob in results.Results) - { - if (preExistingBlobs.Contains(blob.Uri)) - { - continue; - } - else - { - if (blob is CloudPageBlob) - { - ((CloudPageBlob)blob).Delete(); - } - else - { - ((CloudBlockBlob)blob).Delete(); - } - - listedBlobs.Add(blob.Uri); - } - } - } - while (token != null); - - Assert.AreEqual(5, listedBlobs.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedWithPrefixAPM() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - rootContainer.CreateIfNotExists(); - container.Create(); - - List blobNames = CreateBlobs(container, 3, BlobType.BlockBlob); - List rootBlobNames = CreateBlobs(rootContainer, 2, BlobType.BlockBlob); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - BlobResultSegment results; - BlobContinuationToken token = null; - do - { - result = blobClient.BeginListBlobsSegmented("bb", token, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - results = blobClient.EndListBlobsSegmented(result); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - blob.Delete(); - rootBlobNames.Remove(blob.Name); - } - } - while (token != null); - Assert.AreEqual(0, rootBlobNames.Count); - - result = blobClient.BeginListBlobsSegmented("bb", token, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - results = blobClient.EndListBlobsSegmented(result); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - result = blobClient.BeginListBlobsSegmented(name, token, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - results = blobClient.EndListBlobsSegmented(result); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - token = null; - do - { - result = blobClient.BeginListBlobsSegmented(name + "/", token, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - results = blobClient.EndListBlobsSegmented(result); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedWithPrefixTask() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - rootContainer.CreateIfNotExistsAsync().Wait(); - container.CreateAsync().Wait(); - - List blobNames = CreateBlobsTask(container, 3, BlobType.BlockBlob); - List rootBlobNames = CreateBlobsTask(rootContainer, 2, BlobType.BlockBlob); - - BlobResultSegment results; - BlobContinuationToken token = null; - do - { - results = blobClient.ListBlobsSegmentedAsync("bb", token).Result; - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - blob.DeleteAsync().Wait(); - rootBlobNames.Remove(blob.Name); - } - } - while (token != null); - Assert.AreEqual(0, rootBlobNames.Count); - - results = blobClient.ListBlobsSegmentedAsync("bb", token).Result; - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - results = blobClient.ListBlobsSegmentedAsync(name, token).Result; - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - token = null; - do - { - results = blobClient.ListBlobsSegmentedAsync(name + "/", token).Result; - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test BlobClient ListBlobsSegmented - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedPrefixCurrentTokenTask() - { - string containerName = GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(containerName); - int blobCount = 3; - - string prefix = containerName + "/bb"; - BlobContinuationToken currentToken = null; - - try - { - container.CreateAsync().Wait(); - - List blobNames = CreateBlobsTask(container, blobCount, BlobType.BlockBlob); - - int totalCount = 0; - do - { - BlobResultSegment resultSegment = blobClient.ListBlobsSegmentedAsync(prefix, currentToken).Result; - currentToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlockBlob blockBlob in resultSegment.Results) - { - Assert.AreEqual(BlobType.BlockBlob, blockBlob.BlobType); - Assert.IsTrue(blockBlob.Name.StartsWith("bb")); - ++count; - } - - totalCount += count; - } - while (currentToken != null); - - Assert.AreEqual(blobCount, totalCount); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test BlobClient ListBlobsSegmented - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedPrefixCurrentTokenCancellationTokenTask() - { - string containerName = GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(containerName); - int blobCount = 3; - - string prefix = containerName + "/bb"; - BlobContinuationToken currentToken = null; - CancellationToken cancellationToken = new CancellationToken(); - - try - { - container.CreateAsync().Wait(); - - List blobNames = CreateBlobsTask(container, blobCount, BlobType.BlockBlob); - - int totalCount = 0; - do - { - BlobResultSegment resultSegment = blobClient.ListBlobsSegmentedAsync(prefix, currentToken, cancellationToken).Result; - currentToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlockBlob blockBlob in resultSegment.Results) - { - Assert.AreEqual(BlobType.BlockBlob, blockBlob.BlobType); - Assert.IsTrue(blockBlob.Name.StartsWith("bb")); - ++count; - } - - totalCount += count; - } - while (currentToken != null); - - Assert.AreEqual(blobCount, totalCount); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test BlobClient ListBlobsSegmented - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedPrefixUseFlatBlobListingDetailsMaxResultsCurrentTokenOptionsOperationContextTask() - { - string containerName = GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(containerName); - int blobCount = 3; - - string prefix = containerName + "/bb"; - bool useFlatBlobListing = false; - BlobListingDetails blobListingDetails = BlobListingDetails.None; - int? maxResults = 10; - BlobContinuationToken currentToken = null; - BlobRequestOptions options = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - - try - { - container.CreateAsync().Wait(); - - List blobNames = CreateBlobsTask(container, blobCount, BlobType.BlockBlob); - - int totalCount = 0; - do - { - BlobResultSegment resultSegment = blobClient.ListBlobsSegmentedAsync(prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext).Result; - currentToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlockBlob blockBlob in resultSegment.Results) - { - Assert.AreEqual(BlobType.BlockBlob, blockBlob.BlobType); - Assert.IsTrue(blockBlob.Name.StartsWith("bb")); - ++count; - } - - totalCount += count; - - Assert.IsTrue(count <= maxResults.Value); - } - while (currentToken != null); - - Assert.AreEqual(blobCount, totalCount); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test BlobClient ListBlobsSegmented - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListBlobsSegmentedPrefixUseFlatBlobListingDetailsMaxResultsCurrentTokenOptionsOperationContextCancellationTokenTask() - { - string containerName = GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(containerName); - int blobCount = 3; - - string prefix = containerName + "/bb"; - bool useFlatBlobListing = false; - BlobListingDetails blobListingDetails = BlobListingDetails.None; - int? maxResults = 10; - BlobContinuationToken currentToken = null; - BlobRequestOptions options = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = new CancellationToken(); - - try - { - container.CreateAsync().Wait(); - - List blobNames = CreateBlobsTask(container, blobCount, BlobType.BlockBlob); - - int totalCount = 0; - do - { - BlobResultSegment resultSegment = blobClient.ListBlobsSegmentedAsync(prefix, useFlatBlobListing, blobListingDetails, maxResults, currentToken, options, operationContext, cancellationToken).Result; - currentToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlockBlob blockBlob in resultSegment.Results) - { - Assert.AreEqual(BlobType.BlockBlob, blockBlob.BlobType); - Assert.IsTrue(blockBlob.Name.StartsWith("bb")); - ++count; - } - - totalCount += count; - - Assert.IsTrue(count <= maxResults.Value); - } - while (currentToken != null); - - Assert.AreEqual(blobCount, totalCount); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("List containers")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainers() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - IEnumerable results = blobClient.ListContainers(); - - foreach (CloudBlobContainer container in results) - { - if (containerNames.Remove(container.Name)) - { - container.Delete(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - [Description("List containers with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersWithPrefix() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - IEnumerable results = blobClient.ListContainers(name, ContainerListingDetails.None, null, null); - Assert.AreEqual(containerNames.Count, results.Count()); - foreach (CloudBlobContainer container in results) - { - Assert.IsTrue(containerNames.Remove(container.Name)); - container.Delete(); - } - - results = blobClient.ListContainers(name, ContainerListingDetails.None, null, null); - Assert.AreEqual(0, results.Count()); - } - - [TestMethod] - [Description("List containers with prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersWithPrefixSegmented() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmented(name, ContainerListingDetails.None, 1, token); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - Assert.IsTrue(count <= 1); - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - blobClient.GetContainerReference(containerName).Delete(); - } - } - - [TestMethod] - [Description("List containers with a prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersWithPrefixSegmented2() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmented(name, token); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - blobClient.GetContainerReference(containerName).Delete(); - } - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - [Description("List containers")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersWithPrefixSegmentedAPM() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - do - { - result = blobClient.BeginListContainersSegmented(name, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - ContainerResultSegment resultSegment = blobClient.EndListContainersSegmented(result); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - blobClient.GetContainerReference(containerName).Delete(); - } - Assert.AreEqual(0, containerNames.Count); - } - } - -#if TASK - [TestMethod] - [Description("List containers with prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersWithPrefixSegmentedTask() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(name, token).Result; - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - Assert.AreEqual(0, containerNames.Count); - } -#endif - - [TestMethod] - [Description("List more than 5K containers with prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric)] - public void CloudBlobClientListManyContainersSegmentedWithPrefix() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 5050; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmented(name, ContainerListingDetails.None, 1, token); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - Assert.IsTrue(count <= 1); - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - blobClient.GetContainerReference(containerName).Delete(); - } - } - - [TestMethod] - [Description("Test Create Container with Shared Key Lite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientCreateContainerSharedKeyLite() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string containerName = GetRandomContainerName(); - CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName); - blobContainer.Create(); - - bool exists = blobContainer.Exists(); - Assert.IsTrue(exists); - - blobContainer.Delete(); - } - - [TestMethod] - [Description("List containers using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmented() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmented(token); - token = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - foreach (string containerName in listedContainerNames) - { - if (containerNames.Remove(containerName)) - { - blobClient.GetContainerReference(containerName).Delete(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - [Description("List containers")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedAPM() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).Create(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - do - { - result = blobClient.BeginListContainersSegmented(token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - ContainerResultSegment resultSegment = blobClient.EndListContainersSegmented(result); - token = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - foreach (string containerName in listedContainerNames) - { - if (containerNames.Remove(containerName)) - { - blobClient.GetContainerReference(containerName).Delete(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - } - -#if TASK - [TestMethod] - [Description("List containers using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedTask() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(token).Result; - token = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - foreach (string containerName in listedContainerNames) - { - if (containerNames.Remove(containerName)) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedContinuationTokenTask() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - BlobContinuationToken continuationToken = null; - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(continuationToken).Result; - continuationToken = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - } - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedContinuationTokenCancellationTokenTask() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - BlobContinuationToken continuationToken = null; - CancellationToken cancellationToken = CancellationToken.None; - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(continuationToken, cancellationToken).Result; - continuationToken = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - } - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedPrefixContinuationToken() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - string prefix = containerNamePrefix; - BlobContinuationToken continuationToken = null; - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(prefix, continuationToken).Result; - continuationToken = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - } - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedPrefixContinuationTokenCancellationTokenTask() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - string prefix = containerNamePrefix; - BlobContinuationToken continuationToken = null; - CancellationToken cancellationToken = CancellationToken.None; - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(prefix, continuationToken, cancellationToken).Result; - continuationToken = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - } - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedPrefixDetailsIncludedMaxResultsContinuationTokenOptionsOperationContextTask() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - string prefix = containerNamePrefix; - ContainerListingDetails detailsIncluded = ContainerListingDetails.None; - int? maxResults = 10; - BlobContinuationToken continuationToken = null; - BlobRequestOptions options = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(prefix, detailsIncluded, maxResults, continuationToken, options, operationContext).Result; - continuationToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - ++count; - } - - Assert.IsTrue(count <= maxResults.Value); - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } - - [TestMethod] - [Description("CloudBlobClient ListContainersSegmentedAsync - Task")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientListContainersSegmentedPrefixDetailsIncludedMaxResultsContinuationTokenOptionsOperationContextCancellationTokenTask() - { - int containerCount = 3; - string containerNamePrefix = GetRandomContainerName(); - List containerNames = new List(containerCount); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - string prefix = containerNamePrefix; - ContainerListingDetails detailsIncluded = ContainerListingDetails.None; - int? maxResults = 10; - BlobContinuationToken continuationToken = null; - BlobRequestOptions options = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - for (int i = 0; i < containerCount; ++i) - { - string containerName = containerNamePrefix + i.ToString(); - containerNames.Add(containerName); - blobClient.GetContainerReference(containerName).CreateAsync().Wait(); - } - - int totalCount = 0; - do - { - ContainerResultSegment resultSegment = blobClient.ListContainersSegmentedAsync(prefix, detailsIncluded, maxResults, continuationToken, options, operationContext, cancellationToken).Result; - continuationToken = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - if (containerNames.Contains(container.Name)) - { - ++totalCount; - } - ++count; - } - - Assert.IsTrue(count <= maxResults.Value); - } - while (continuationToken != null); - - Assert.AreEqual(containerCount, totalCount); - } - finally - { - foreach (string containerName in containerNames) - { - blobClient.GetContainerReference(containerName).DeleteAsync().Wait(); - } - } - } -#endif - - [TestMethod] - [Description("Upload a blob with a small maximum execution time")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientMaximumExecutionTimeout() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(40 * 1024 * 1024); - - try - { - container.Create(); - - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(5); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - blockBlob.UploadFromStream(ms); - } - catch (TimeoutException ex) - { - Assert.IsInstanceOfType(ex, typeof(TimeoutException)); - } - catch (StorageException ex) - { - Assert.IsInstanceOfType(ex.InnerException, typeof(TimeoutException)); - } - } - - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - pageBlob.UploadFromStream(ms); - } - catch (TimeoutException ex) - { - Assert.IsInstanceOfType(ex, typeof(TimeoutException)); - } - catch (StorageException ex) - { - Assert.IsInstanceOfType(ex.InnerException, typeof(TimeoutException)); - } - } - } - - finally - { - blobClient.MaximumExecutionTime = null; - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Make sure MaxExecutionTime is not enforced when using streams")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientMaximumExecutionTimeoutShouldNotBeHonoredForStreams() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(1024 * 1024); - - try - { - container.Create(); - - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(30); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - blockBlob.StreamWriteSizeInBytes = 1024 * 1024; - blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - pageBlob.StreamWriteSizeInBytes = 1024 * 1024; - pageBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - - using (CloudBlobStream bos = blockBlob.OpenWrite()) - { - DateTime start = DateTime.Now; - - for (int i = 0; i < 7; i++) - { - bos.Write(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - Thread.Sleep(msRemaining); - } - - bos.Write(buffer, 0, buffer.Length); - } - - using (Stream bis = blockBlob.OpenRead()) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += bis.Read(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - Thread.Sleep(msRemaining); - } - - while (true) - { - int count = bis.Read(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - - using (CloudBlobStream bos = pageBlob.OpenWrite(8 * 1024 * 1024)) - { - DateTime start = DateTime.Now; - - for (int i = 0; i < 7; i++) - { - bos.Write(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - Thread.Sleep(msRemaining); - } - - bos.Write(buffer, 0, buffer.Length); - } - - using (Stream bis = pageBlob.OpenRead()) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += bis.Read(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - Thread.Sleep(msRemaining); - } - - while (true) - { - int count = bis.Read(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - } - - finally - { - - blobClient.MaximumExecutionTime = null; - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobContainerTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobContainerTest.cs deleted file mode 100644 index ac6b3a36f3bd9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobContainerTest.cs +++ /dev/null @@ -1,2952 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobContainerTest : BlobTestBase - { - private static void TestAccess(BlobContainerPublicAccessType accessType, CloudBlobContainer container, ICloudBlob inputBlob) - { - StorageCredentials credentials = new StorageCredentials(); - container = new CloudBlobContainer(container.Uri, credentials); - CloudPageBlob blob = new CloudPageBlob(inputBlob.Uri, credentials); - - if (accessType.Equals(BlobContainerPublicAccessType.Container)) - { - blob.FetchAttributes(); - container.ListBlobs().ToArray(); - container.FetchAttributes(); - } - else if (accessType.Equals(BlobContainerPublicAccessType.Blob)) - { - blob.FetchAttributes(); - TestHelper.ExpectedException( - () => container.ListBlobs().ToArray(), - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - TestHelper.ExpectedException( - () => container.FetchAttributes(), - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - else - { - TestHelper.ExpectedException( - () => blob.FetchAttributes(), - "Fetch blob attributes while public access does not allow", - HttpStatusCode.NotFound); - TestHelper.ExpectedException( - () => container.ListBlobs().ToArray(), - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - TestHelper.ExpectedException( - () => container.FetchAttributes(), - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - } - -#if TASK - private static void TestAccessTask(BlobContainerPublicAccessType accessType, CloudBlobContainer container, ICloudBlob inputBlob) - { - StorageCredentials credentials = new StorageCredentials(); - container = new CloudBlobContainer(container.Uri, credentials); - CloudPageBlob blob = new CloudPageBlob(inputBlob.Uri, credentials); - - if (accessType.Equals(BlobContainerPublicAccessType.Container)) - { - blob.FetchAttributesAsync().Wait(); - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented(token); - results.Results.ToArray(); - token = results.ContinuationToken; - } - while (token != null); - container.FetchAttributesAsync().Wait(); - } - else if (accessType.Equals(BlobContainerPublicAccessType.Blob)) - { - blob.FetchAttributesAsync().Wait(); - - TestHelper.ExpectedExceptionTask( - container.ListBlobsSegmentedAsync(null), - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - TestHelper.ExpectedExceptionTask( - container.FetchAttributesAsync(), - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - else - { - TestHelper.ExpectedExceptionTask( - blob.FetchAttributesAsync(), - "Fetch blob attributes while public access does not allow", - HttpStatusCode.NotFound); - TestHelper.ExpectedExceptionTask( - container.ListBlobsSegmentedAsync(null), - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - TestHelper.ExpectedExceptionTask( - container.FetchAttributesAsync(), - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - } -#endif - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Validate container references")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerReference() - { - CloudBlobClient client = GenerateCloudBlobClient(); - CloudBlobContainer container = client.GetContainerReference("container"); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("directory1/blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("directory2/blob2"); - CloudBlobDirectory directory = container.GetDirectoryReference("directory3"); - CloudBlobDirectory directory2 = directory.GetSubdirectoryReference("directory4"); - - Assert.AreEqual(container, blockBlob.Container); - Assert.AreEqual(container, pageBlob.Container); - Assert.AreEqual(container, directory.Container); - Assert.AreEqual(container, directory2.Container); - Assert.AreEqual(container, directory2.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - } - - [TestMethod] - [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreate() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - TestHelper.ExpectedException( - () => container.Create(), - "Creating already exists container should fail", - HttpStatusCode.Conflict); - container.Delete(); - } - - [TestMethod] - [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreate( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndCreate(result); - result = container.BeginCreate( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => container.EndCreate(result), - "Creating already exists container should fail", - HttpStatusCode.Conflict); - } - container.Delete(); - } - -#if TASK - [TestMethod] - [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - - AggregateException e = TestHelper.ExpectedException( - container.CreateAsync().Wait, - "Creating already exists container should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(StorageException)); - Assert.AreEqual((int)HttpStatusCode.Conflict, ((StorageException)e.InnerException).RequestInformation.HttpStatusCode); - Task.Factory.FromAsync(container.BeginDelete, container.EndDelete, null).Wait(); - } - - [TestMethod] - [Description("Create and delete a container with access type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateTaskWithContainerAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - CancellationTokenSource cts = new CancellationTokenSource(); - - container.CreateAsync(BlobContainerPublicAccessType.Container, null, null, cts.Token).Wait(); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - - Task.Factory.FromAsync(container.BeginDelete, container.EndDelete, null).Wait(); - } - - [TestMethod] - [Description("Create and delete a container with access type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateTaskWithBlobAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - CancellationTokenSource cts = new CancellationTokenSource(); - container.CreateAsync(BlobContainerPublicAccessType.Blob, null, null, cts.Token).Wait(); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - - Task.Factory.FromAsync(container.BeginDelete, container.EndDelete, null).Wait(); - } - - [TestMethod] - [Description("Create and delete a container with access type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateTaskWithPrivateAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - CancellationTokenSource cts = new CancellationTokenSource(); - container.CreateAsync(BlobContainerPublicAccessType.Off, null, null, cts.Token).Wait(); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - - Task.Factory.FromAsync(container.BeginDelete, container.EndDelete, null).Wait(); - } - - [TestMethod] - [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateTaskWithCancellation() - { - CloudBlobContainer container = GetRandomContainerReference(); - CancellationTokenSource cts = new CancellationTokenSource(); - OperationContext ctx = new OperationContext(); - - Task createTask = container.CreateAsync(BlobContainerPublicAccessType.Off, null, ctx, cts.Token); - try - { - Thread.Sleep(0); - cts.Cancel(); - createTask.Wait(); - - // Should throw aggregate exception - Assert.Fail(); - } - catch (Exception ex) - { - Assert.IsInstanceOfType(ex, typeof(AggregateException)); - Assert.IsNotNull(ex.InnerException); - Assert.IsInstanceOfType(ex.InnerException, typeof(OperationCanceledException)); - } - - // Validate that we did attempt one request and it was cancelled - TestHelper.AssertCancellation(ctx); - } -#endif - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(container.CreateIfNotExists()); - Assert.IsFalse(container.CreateIfNotExists()); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithContainerAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(container.CreateIfNotExists(BlobContainerPublicAccessType.Container)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - - Assert.IsFalse(container.CreateIfNotExists(BlobContainerPublicAccessType.Container)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithContainerAccessTypeAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Container, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(container.EndCreateIfNotExists(result)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - - result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Container, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndCreateIfNotExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithBlobAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(container.CreateIfNotExists(BlobContainerPublicAccessType.Blob)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - - Assert.IsFalse(container.CreateIfNotExists(BlobContainerPublicAccessType.Container)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithBlobAccessTypeAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Blob, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(container.EndCreateIfNotExists(result)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - - result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Blob, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndCreateIfNotExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithPrivateAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(container.CreateIfNotExists(BlobContainerPublicAccessType.Off)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - - Assert.IsFalse(container.CreateIfNotExists(BlobContainerPublicAccessType.Container)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsWithPrivateAccessTypeAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Off, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(container.EndCreateIfNotExists(result)); - - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - - result = container.BeginCreateIfNotExists(BlobContainerPublicAccessType.Off, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndCreateIfNotExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreateIfNotExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(container.EndCreateIfNotExists(result)); - result = container.BeginCreateIfNotExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndCreateIfNotExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateIfNotExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(container.CreateIfNotExistsAsync().Result); - Assert.IsFalse(container.CreateIfNotExistsAsync().Result); - } - finally - { - container.DeleteIfExists(); - } - } -#endif - - [TestMethod] - [Description("Try to delete a non-existing container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerDeleteIfExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - Assert.IsFalse(container.DeleteIfExists()); - container.Create(); - Assert.IsTrue(container.DeleteIfExists()); - Assert.IsFalse(container.DeleteIfExists()); - } - - [TestMethod] - [Description("Try to delete a non-existing container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerDeleteIfExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndDeleteIfExists(result)); - result = container.BeginCreate( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndCreate(result); - result = container.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(container.EndDeleteIfExists(result)); - result = container.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(container.EndDeleteIfExists(result)); - } - } - -#if TASK - [TestMethod] - [Description("Try to delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerDeleteTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - Assert.IsTrue(container.Exists()); - container.DeleteAsync().Wait(); - Assert.IsFalse(container.Exists()); - } - - [TestMethod] - [Description("Try to delete a non-existing container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerDeleteIfExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - Assert.IsFalse(container.DeleteIfExistsAsync().Result); - container.CreateAsync().Wait(); - Assert.IsTrue(container.DeleteIfExistsAsync().Result); - Assert.IsFalse(container.DeleteIfExistsAsync().Result); - } -#endif - - [TestMethod] - [Description("Check a container's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - - Assert.IsFalse(container2.Exists()); - - container.Create(); - - try - { - Assert.IsTrue(container2.Exists()); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.Delete(); - } - - Assert.IsFalse(container2.Exists()); - } - - [TestMethod] - [Description("Check a container's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(container2.EndExists(result)); - - container.Create(); - - try - { - result = container2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(container2.EndExists(result)); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.Delete(); - } - - result = container2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(container2.EndExists(result)); - } - } - -#if TASK - [TestMethod] - [Description("Check a container's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - - Assert.IsFalse(container2.ExistsAsync().Result); - - container.CreateAsync().Wait(); - - try - { - Assert.IsTrue(container2.ExistsAsync().Result); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteAsync().Wait(); - } - - Assert.IsFalse(container2.ExistsAsync().Result); - } -#endif - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - container.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = container2.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissionsOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - container.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = container2.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissionsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginSetPermissions(permissions, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndSetPermissions(result); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - result = container.BeginGetPermissions(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - permissions = container.EndGetPermissions(result); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissionsAPMOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginSetPermissions(permissions, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndSetPermissions(result); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - result = container.BeginGetPermissions(null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - permissions = container.EndGetPermissions(result); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissionsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissionsAsync().Result; - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - container.SetPermissionsAsync(permissions).Wait(); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = container2.GetPermissionsAsync().Result; - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExistsAsync(); - } - } - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetPermissionsOverloadTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - BlobContainerPermissions permissions = container.GetPermissionsAsync().Result; - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - container.SetPermissionsAsync(permissions).Wait(); - Thread.Sleep(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = container2.GetPermissionsAsync().Result; - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExists(); - } - } -#endif - - [TestMethod] - [Description("Clear container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerClearPermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - container.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - - Assert.AreEqual(true, permissions.SharedAccessPolicies.Contains(sharedAccessPolicy)); - Assert.AreEqual(true, permissions.SharedAccessPolicies.ContainsKey("key1")); - permissions.SharedAccessPolicies.Clear(); - container.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - permissions = container.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCopyPermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry2 = start.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - - KeyValuePair[] sharedAccessPolicyArray = new KeyValuePair[2]; - permissions.SharedAccessPolicies.CopyTo(sharedAccessPolicyArray, 0); - Assert.AreEqual(2, sharedAccessPolicyArray.Length); - Assert.AreEqual(sharedAccessPolicy, sharedAccessPolicyArray[0]); - Assert.AreEqual(sharedAccessPolicy2, sharedAccessPolicyArray[1]); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Remove container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerRemovePermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - container.SetPermissions(permissions); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions.SharedAccessPolicies.Remove(sharedAccessPolicy2); - container.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - permissions = container.GetPermissions(); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.AreEqual(sharedAccessPolicy.Key, permissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, permissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - container.SetPermissions(permissions); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions.SharedAccessPolicies.Remove("key2"); - container.SetPermissions(permissions); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - permissions = container.GetPermissions(); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.AreEqual(sharedAccessPolicy.Key, permissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, permissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("TryGetValue for container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerTryGetValuePermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - container.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions = container.GetPermissions(); - SharedAccessBlobPolicy retrPolicy; - permissions.SharedAccessPolicies.TryGetValue("key1", out retrPolicy); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, retrPolicy.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, retrPolicy.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, retrPolicy.SharedAccessExpiryTime); - - SharedAccessBlobPolicy retrPolicy2; - permissions.SharedAccessPolicies.TryGetValue("key2", out retrPolicy2); - Assert.AreEqual(sharedAccessPolicy2.Value.Permissions, retrPolicy2.Permissions); - Assert.AreEqual(sharedAccessPolicy2.Value.SharedAccessStartTime, retrPolicy2.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy2.Value.SharedAccessExpiryTime, retrPolicy2.SharedAccessExpiryTime); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("GetEnumerator for container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetEnumeratorPermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - IEnumerator> policies = permissions.SharedAccessPolicies.GetEnumerator(); - policies.MoveNext(); - Assert.AreEqual(sharedAccessPolicy, policies.Current); - policies.MoveNext(); - Assert.AreEqual(sharedAccessPolicy2, policies.Current); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("GetValues for container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetValuesPermissions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - BlobContainerPermissions permissions = container.GetPermissions(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessBlobPermissions.List, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - ICollection values = permissions.SharedAccessPolicies.Values; - Assert.AreEqual(2, values.Count); - Assert.AreEqual(sharedAccessPolicy.Value, values.ElementAt(0)); - Assert.AreEqual(sharedAccessPolicy2.Value, values.ElementAt(1)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Get permissions from string")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerPermissionsFromString() - { - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy(); - policy.SharedAccessStartTime = DateTime.UtcNow; - policy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("rwdl"); - Assert.AreEqual(SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Delete | SharedAccessBlobPermissions.List, policy.Permissions); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("rwl"); - Assert.AreEqual(SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List, policy.Permissions); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("rw"); - Assert.AreEqual(SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, policy.Permissions); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("rd"); - Assert.AreEqual(SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Delete, policy.Permissions); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("wl"); - Assert.AreEqual(SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List, policy.Permissions); - - policy.Permissions = SharedAccessBlobPolicy.PermissionsFromString("w"); - Assert.AreEqual(SharedAccessBlobPermissions.Write, policy.Permissions); - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithContainerAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Container); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithContainerAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Container, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithContainerAccessTypeAPMOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreate(BlobContainerPublicAccessType.Container, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndCreate(result); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Container, container, blob1); - TestAccess(BlobContainerPublicAccessType.Container, container, blob2); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("APM - Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithContainerAccessTypeOverloadTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.CreateAsync(BlobContainerPublicAccessType.Container, null, null).Wait(); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.CreateAsync(0).Wait(); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.CreateAsync(0).Wait(); - - TestAccessTask(BlobContainerPublicAccessType.Container, container, blob1); - TestAccessTask(BlobContainerPublicAccessType.Container, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithBlobAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Blob); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithBlobAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Blob, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithBlobAccessTypeAPMOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreate(BlobContainerPublicAccessType.Blob, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndCreate(result); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Blob, container, blob1); - TestAccess(BlobContainerPublicAccessType.Blob, container, blob2); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithPrivateAccessType() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Off); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithPrivateAccessTypeOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(BlobContainerPublicAccessType.Off, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("APM - Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithPrivateAccessTypeAPMOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginCreate(BlobContainerPublicAccessType.Off, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndCreate(result); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - blob1.Create(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - blob2.Create(0); - - TestAccess(BlobContainerPublicAccessType.Off, container, blob1); - TestAccess(BlobContainerPublicAccessType.Off, container, blob2); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("key1", "value1"); - container.Create(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - container2.FetchAttributes(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - Assert.IsTrue(container2.Properties.LastModified.Value.AddHours(1) > DateTimeOffset.Now); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerCreateWithMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("key1", "value1"); - container.CreateAsync().Wait(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - container2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - Assert.IsTrue(container2.Properties.LastModified.Value.AddHours(1) > DateTimeOffset.Now); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExistsAsync(); - } - } -#endif - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - container2.FetchAttributes(); - Assert.AreEqual(0, container2.Metadata.Count); - - container.Metadata.Add("key1", "value1"); - container.SetMetadata(); - - container2.FetchAttributes(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - CloudBlobContainer container3 = container.ServiceClient.ListContainers(container.Name, ContainerListingDetails.Metadata).First(); - Assert.AreEqual(1, container3.Metadata.Count); - Assert.AreEqual("value1", container3.Metadata["key1"]); - - container.Metadata.Clear(); - container.SetMetadata(); - - container2.FetchAttributes(); - Assert.AreEqual(0, container2.Metadata.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerRegionalSetMetadata() - { - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("sk-SK"); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("sequence", "value"); - container.Metadata.Add("schema", "value"); - container.Create(); - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetMetadataAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - IAsyncResult result = container2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container2.EndFetchAttributes(result); - Assert.AreEqual(0, container2.Metadata.Count); - - container.Metadata.Add("key1", "value1"); - result = container.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndSetMetadata(result); - - result = container2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container2.EndFetchAttributes(result); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - result = container.ServiceClient.BeginListContainersSegmented(container.Name, ContainerListingDetails.Metadata, null, null, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - CloudBlobContainer container3 = container.ServiceClient.EndListContainersSegmented(result).Results.First(); - Assert.AreEqual(1, container3.Metadata.Count); - Assert.AreEqual("value1", container3.Metadata["key1"]); - - container.Metadata.Clear(); - result = container.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndSetMetadata(result); - - result = container2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container2.EndFetchAttributes(result); - Assert.AreEqual(0, container2.Metadata.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSetMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - container2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, container2.Metadata.Count); - - container.Metadata.Add("key1", "value1"); - container.SetMetadataAsync().Wait(); - - container2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - CloudBlobContainer container3 = - container.ServiceClient.ListContainersSegmentedAsync( - container.Name, ContainerListingDetails.Metadata, null, null, null, null).Result.Results.First(); - Assert.AreEqual(1, container3.Metadata.Count); - Assert.AreEqual("value1", container3.Metadata["key1"]); - - container.Metadata.Clear(); - container.SetMetadataAsync().Wait(); - - container2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, container2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobs() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - IEnumerable results = container.ListBlobs(); - Assert.AreEqual(blobNames.Count, results.Count()); - foreach (IListBlobItem blobItem in results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List many blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric)] - public void CloudBlobContainerListManyBlobs() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List pageBlobNames = CreateBlobs(container, 3000, BlobType.PageBlob); - List blockBlobNames = CreateBlobs(container, 3000, BlobType.BlockBlob); - - int count = 0; - IEnumerable results = container.ListBlobs(); - foreach (IListBlobItem blobItem in results) - { - count++; - Assert.IsInstanceOfType(blobItem, typeof(ICloudBlob)); - ICloudBlob blob = (ICloudBlob)blobItem; - if (pageBlobNames.Remove(blob.Name)) - { - Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); - } - else if (blockBlobNames.Remove(blob.Name)) - { - Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); - } - else - { - Assert.Fail("Unexpected blob: " + blob.Uri.AbsoluteUri); - } - } - - Assert.AreEqual(6000, count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmented() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented(null, true, BlobListingDetails.None, 1, token, null, null); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.IsTrue(count <= 1); - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - BlobContinuationToken token = null; - do - { - IAsyncResult result = container.BeginListBlobsSegmented(null, true, BlobListingDetails.None, 1, token, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.IsTrue(count <= 1); - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - List blobNames = CreateBlobsTask(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, 1, token, null, null).Result; - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.IsTrue(count <= 1); - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented(token); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedAPMOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - BlobContinuationToken token = null; - do - { - IAsyncResult result = container.BeginListBlobsSegmented(null, token, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedOverloadTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmentedAsync(null, token).Result; - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync(); - } - } -#endif - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerListBlobsSegmentedWithPrefixOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented("pb", token); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify GetSchema, WriteXml and ReadXml on BlobContinuationToken")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobContinuationTokenVerifyXmlFunctions() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented(null, true, BlobListingDetails.None, 1, token, null, null); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.IsTrue(count <= 1); - token = results.ContinuationToken; - - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - token.WriteXml(writer); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new BlobContinuationToken(); - token.ReadXml(reader); - } - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify GetSchema, WriteXml and ReadXml on BlobContinuationToken within another Xml")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobContinuationTokenVerifyXmlWithinXml() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - List blobNames = CreateBlobs(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = container.ListBlobsSegmented(null, true, BlobListingDetails.None, 1, token, null, null); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.IsTrue(count <= 1); - token = results.ContinuationToken; - - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - writer.WriteStartElement("test1"); - writer.WriteStartElement("test2"); - token.WriteXml(writer); - writer.WriteEndElement(); - writer.WriteEndElement(); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new BlobContinuationToken(); - reader.ReadStartElement(); - reader.ReadStartElement(); - token.ReadXml(reader); - reader.ReadEndElement(); - reader.ReadEndElement(); - } - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServer() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - Permissions = SharedAccessBlobPermissions.Read, - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - }; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("bb"); - blockBlob.PutBlockList(new string[] { }); - - CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); - pageBlob.Create(0); - - ICloudBlob blob1 = container.GetBlobReferenceFromServer("bb"); - Assert.IsInstanceOfType(blob1, typeof(CloudBlockBlob)); - - CloudBlockBlob blob1Snapshot = ((CloudBlockBlob)blob1).CreateSnapshot(); - blob1.SetProperties(); - Uri blob1SnapshotUri = new Uri(blob1Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob1Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob1SnapshotReference = container.ServiceClient.GetBlobReferenceFromServer(blob1SnapshotUri); - AssertAreEqual(blob1Snapshot.Properties, blob1SnapshotReference.Properties); - - ICloudBlob blob2 = container.GetBlobReferenceFromServer("pb"); - Assert.IsInstanceOfType(blob2, typeof(CloudPageBlob)); - - CloudPageBlob blob2Snapshot = ((CloudPageBlob)blob2).CreateSnapshot(); - blob2.SetProperties(); - Uri blob2SnapshotUri = new Uri(blob2Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob2Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob2SnapshotReference = container.ServiceClient.GetBlobReferenceFromServer(blob2SnapshotUri); - AssertAreEqual(blob2Snapshot.Properties, blob2SnapshotReference.Properties); - - ICloudBlob blob3 = container.ServiceClient.GetBlobReferenceFromServer(blockBlob.Uri); - Assert.IsInstanceOfType(blob3, typeof(CloudBlockBlob)); - - ICloudBlob blob4 = container.ServiceClient.GetBlobReferenceFromServer(pageBlob.Uri); - Assert.IsInstanceOfType(blob4, typeof(CloudPageBlob)); - - string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); - StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); - Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); - - string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); - StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); - Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); - - ICloudBlob blob5 = container.ServiceClient.GetBlobReferenceFromServer(blockBlobSASUri); - Assert.IsInstanceOfType(blob5, typeof(CloudBlockBlob)); - - ICloudBlob blob6 = container.ServiceClient.GetBlobReferenceFromServer(pageBlobSASUri); - Assert.IsInstanceOfType(blob6, typeof(CloudPageBlob)); - - CloudBlobClient client7 = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); - ICloudBlob blob7 = client7.GetBlobReferenceFromServer(blockBlobSASUri); - Assert.IsInstanceOfType(blob7, typeof(CloudBlockBlob)); - - CloudBlobClient client8 = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); - ICloudBlob blob8 = client8.GetBlobReferenceFromServer(pageBlobSASUri); - Assert.IsInstanceOfType(blob8, typeof(CloudPageBlob)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - Permissions = SharedAccessBlobPermissions.Read, - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - }; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("bb"); - blockBlob.PutBlockList(new string[] { }); - - CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); - pageBlob.Create(0); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginGetBlobReferenceFromServer("bb", - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob1 = container.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob1, typeof(CloudBlockBlob)); - - result = ((CloudBlockBlob)blob1).BeginCreateSnapshot( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - CloudBlockBlob blob1Snapshot = ((CloudBlockBlob)blob1).EndCreateSnapshot(result); - result = blob1.BeginSetProperties( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob1.EndSetProperties(result); - Uri blob1SnapshotUri = new Uri(blob1Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob1Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - result = container.ServiceClient.BeginGetBlobReferenceFromServer(blob1SnapshotUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob1SnapshotReference = container.ServiceClient.EndGetBlobReferenceFromServer(result); - AssertAreEqual(blob1Snapshot.Properties, blob1SnapshotReference.Properties); - - result = container.BeginGetBlobReferenceFromServer("pb", - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob2 = container.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob2, typeof(CloudPageBlob)); - - result = ((CloudPageBlob)blob2).BeginCreateSnapshot( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - CloudPageBlob blob2Snapshot = ((CloudPageBlob)blob2).EndCreateSnapshot(result); - result = blob2.BeginSetProperties( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndSetProperties(result); - Uri blob2SnapshotUri = new Uri(blob2Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob2Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - result = container.ServiceClient.BeginGetBlobReferenceFromServer(blob2SnapshotUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob2SnapshotReference = container.ServiceClient.EndGetBlobReferenceFromServer(result); - AssertAreEqual(blob2Snapshot.Properties, blob2SnapshotReference.Properties); - - result = container.ServiceClient.BeginGetBlobReferenceFromServer(blockBlob.Uri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob3 = container.ServiceClient.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob3, typeof(CloudBlockBlob)); - - result = container.ServiceClient.BeginGetBlobReferenceFromServer(pageBlob.Uri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob4 = container.ServiceClient.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob4, typeof(CloudPageBlob)); - - string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); - StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); - Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); - - string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); - StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); - Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); - - result = container.ServiceClient.BeginGetBlobReferenceFromServer(blockBlobSASUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob5 = container.ServiceClient.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob5, typeof(CloudBlockBlob)); - - result = container.ServiceClient.BeginGetBlobReferenceFromServer(pageBlobSASUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob6 = container.ServiceClient.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob6, typeof(CloudPageBlob)); - - CloudBlobClient client7 = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); - result = client7.BeginGetBlobReferenceFromServer(blockBlobSASUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob7 = client7.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob7, typeof(CloudBlockBlob)); - - CloudBlobClient client8 = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); - result = client8.BeginGetBlobReferenceFromServer(pageBlobSASUri, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - ICloudBlob blob8 = client8.EndGetBlobReferenceFromServer(result); - Assert.IsInstanceOfType(blob8, typeof(CloudPageBlob)); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - Permissions = SharedAccessBlobPermissions.Read, - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - }; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("bb"); - blockBlob.PutBlockList(new string[] { }); - - CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); - pageBlob.Create(0); - - ICloudBlob blob1 = container.GetBlobReferenceFromServerAsync("bb").Result; - Assert.IsInstanceOfType(blob1, typeof(CloudBlockBlob)); - - ICloudBlob blob2 = container.GetBlobReferenceFromServerAsync("pb").Result; - Assert.IsInstanceOfType(blob2, typeof(CloudPageBlob)); - - ICloudBlob blob3 = container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlob.Uri).Result; - Assert.IsInstanceOfType(blob3, typeof(CloudBlockBlob)); - - ICloudBlob blob4 = container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlob.Uri).Result; - Assert.IsInstanceOfType(blob4, typeof(CloudPageBlob)); - - string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); - StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); - Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); - - string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); - StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); - Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); - - ICloudBlob blob5 = container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSASUri).Result; - Assert.IsInstanceOfType(blob5, typeof(CloudBlockBlob)); - - ICloudBlob blob6 = container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSASUri).Result; - Assert.IsInstanceOfType(blob6, typeof(CloudPageBlob)); - - CloudBlobClient client7 = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); - ICloudBlob blob7 = client7.GetBlobReferenceFromServerAsync(blockBlobSASUri).Result; - Assert.IsInstanceOfType(blob7, typeof(CloudBlockBlob)); - - CloudBlobClient client8 = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); - ICloudBlob blob8 = client8.GetBlobReferenceFromServerAsync(pageBlobSASUri).Result; - Assert.IsInstanceOfType(blob8, typeof(CloudPageBlob)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerBlobNameTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - string blobName = "myblob"; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); - blockBlob.PutBlockListAsync(new string[0]).Wait(); - - ICloudBlob actual = container.GetBlobReferenceFromServerAsync(blobName).Result; - - Assert.IsInstanceOfType(actual, typeof(CloudBlockBlob)); - Assert.AreEqual(BlobType.BlockBlob, ((CloudBlockBlob)actual).BlobType); - Assert.AreEqual(blobName, ((CloudBlockBlob)actual).Name); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerBlobNameCancellationTokenTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - string blobName = "myblob"; - CancellationToken cancellationToken = CancellationToken.None; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); - blockBlob.PutBlockListAsync(new string[0]).Wait(); - - ICloudBlob actual = container.GetBlobReferenceFromServerAsync(blobName, cancellationToken).Result; - - Assert.IsInstanceOfType(actual, typeof(CloudBlockBlob)); - Assert.AreEqual(BlobType.BlockBlob, ((CloudBlockBlob)actual).BlobType); - Assert.AreEqual(blobName, ((CloudBlockBlob)actual).Name); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerBlobNameAccessConditionRequestOptionsOperationContextTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - string blobName = "myblob"; - AccessCondition accessCondition = new AccessCondition(); - accessCondition.IfModifiedSinceTime = DateTime.UtcNow.AddDays(-1.0); - BlobRequestOptions requestOptions = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); - blockBlob.PutBlockListAsync(new string[0]).Wait(); - - ICloudBlob actual = container.GetBlobReferenceFromServerAsync(blobName, accessCondition, requestOptions, operationContext).Result; - - Assert.IsInstanceOfType(actual, typeof(CloudBlockBlob)); - Assert.AreEqual(BlobType.BlockBlob, ((CloudBlockBlob)actual).BlobType); - Assert.AreEqual(blobName, ((CloudBlockBlob)actual).Name); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerGetBlobReferenceFromServerBlobNameAccessConditionRequestOptionsOperationContextCancellationTokenTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - string blobName = "myblob"; - AccessCondition accessCondition = new AccessCondition(); - accessCondition.IfModifiedSinceTime = DateTime.UtcNow.AddDays(-1.0); - BlobRequestOptions requestOptions = new BlobRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName); - blockBlob.PutBlockListAsync(new string[0]).Wait(); - - ICloudBlob actual = container.GetBlobReferenceFromServerAsync(blobName, accessCondition, requestOptions, operationContext, cancellationToken).Result; - - Assert.IsInstanceOfType(actual, typeof(CloudBlockBlob)); - Assert.AreEqual(BlobType.BlockBlob, ((CloudBlockBlob)actual).BlobType); - Assert.AreEqual(blobName, ((CloudBlockBlob)actual).Name); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Test conditional access on a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerConditionalAccess() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - container.FetchAttributes(); - - string currentETag = container.Properties.ETag; - DateTimeOffset currentModifiedTime = container.Properties.LastModified.Value; - - // ETag conditional tests - container.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - container.SetMetadata(); - - container.FetchAttributes(); - string newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - // LastModifiedTime tests - currentModifiedTime = container.Properties.LastModified.Value; - - container.Metadata["DateConditionalName"] = "DateConditionalValue"; - - TestHelper.ExpectedException( - () => container.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null), - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - container.Metadata["DateConditionalName"] = "DateConditionalValue2"; - currentETag = container.Properties.ETag; - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - container.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - container.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - container.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - container.FetchAttributes(); - newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobDirectoryTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobDirectoryTest.cs deleted file mode 100644 index 37cca5a2f9cea..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlobDirectoryTest.cs +++ /dev/null @@ -1,684 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.VisualStudio.TestTools.UnitTesting; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Threading; - - [TestClass] - public class CloudBlobDirectoryTest : BlobTestBase - { - string[] Delimiters = new string[] {"$", "@", "-", "%", "/", "|"}; - - private bool CloudBlobDirectorySetupWithDelimiter(CloudBlobContainer container, string delimiter = "/") - { - try - { - for (int i = 1; i < 3; i++) - { - for (int j = 1; j < 3; j++) - { - for (int k = 1; k < 3; k++) - { - String directory = "TopDir" + i + delimiter + "MidDir" + j + delimiter + "EndDir" + k + delimiter + "EndBlob" + k; - CloudPageBlob blob1 = container.GetPageBlobReference(directory); - blob1.Create(0); - } - } - - CloudPageBlob blob2 = container.GetPageBlobReference("TopDir" + i + delimiter + "Blob" + i); - blob2.Create(0); - } - - return true; - } - catch (StorageException) - { - throw; - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("CloudBlobDirectory get parent of Blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetParent() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - blob.Create(0); - Assert.IsTrue(blob.Exists()); - Assert.AreEqual("Dir1" + delimiter + "Blob1", blob.Name); - CloudBlobDirectory parent = blob.Parent; - Assert.AreEqual(parent.Prefix, "Dir1" + delimiter); - blob.Delete(); - } - - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryFlatListing() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - container.Create(); - if (CloudBlobDirectorySetupWithDelimiter(container, delimiter)) - { - IEnumerable list1 = container.ListBlobs("TopDir1" + delimiter, false, BlobListingDetails.None, null, null); - - List simpleList1 = list1.ToList(); - ////Check if for 3 because if there were more than 3, the previous assert would have failed. - ////So the only thing we need to make sure is that it is not less than 3. - Assert.IsTrue(simpleList1.Count == 3); - - IListBlobItem item11 = simpleList1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - IEnumerable list2 = container.ListBlobs("TopDir1" + delimiter + "MidDir1", true, BlobListingDetails.None, null, null); - - List simpleList2 = list2.ToList(); - Assert.IsTrue(simpleList2.Count == 2); - - IListBlobItem item21 = simpleList2.ElementAt(0); - Assert.IsTrue(item21.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item22 = simpleList2.ElementAt(1); - Assert.IsTrue(item22.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - - IEnumerable list3 = container.ListBlobs("TopDir1" + delimiter + "MidDir1" + delimiter, false, BlobListingDetails.None, null, null); - - List simpleList3 = list3.ToList(); - Assert.IsTrue(simpleList3.Count == 2); - - IListBlobItem item31 = simpleList3.ElementAt(0); - Assert.IsTrue(item31.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter)); - - IListBlobItem item32 = simpleList3.ElementAt(1); - Assert.IsTrue(item32.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter)); - - IEnumerable list4 = midDir2.ListBlobs(true); - - List simpleList4 = list4.ToList(); - Assert.IsTrue(simpleList4.Count == 2); - - IListBlobItem item41 = simpleList4.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = simpleList4.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryFlatListingAPM() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - container.Create(); - if (CloudBlobDirectorySetupWithDelimiter(container, delimiter)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - BlobContinuationToken token = null; - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1"); - List list1 = new List(); - do - { - result = directory.BeginListBlobsSegmented(token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - BlobResultSegment result1 = directory.EndListBlobsSegmented(result); - list1.AddRange(result1.Results); - token = result1.ContinuationToken; - } - while(token!=null); - - Assert.IsTrue(list1.Count == 3); - - IListBlobItem item11 = list1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = list1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = list1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - List list2 = new List(); - do - { - result = midDir2.BeginListBlobsSegmented(true, BlobListingDetails.None, null, token, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - BlobResultSegment result2 = midDir2.EndListBlobsSegmented(result); - list2.AddRange(result2.Results); - token = result2.ContinuationToken; - } - while (token != null); - - Assert.IsTrue(list2.Count == 2); - - IListBlobItem item41 = list2.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = list2.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - } - -#if TASK - [TestMethod] - [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryFlatListingTask() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - container.CreateAsync().Wait(); - if (CloudBlobDirectorySetupWithDelimiter(container, delimiter)) - { - BlobContinuationToken token = null; - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1"); - List list1 = new List(); - do - { - BlobResultSegment result1 = directory.ListBlobsSegmentedAsync(token).Result; - list1.AddRange(result1.Results); - token = result1.ContinuationToken; - } - while (token != null); - - Assert.IsTrue(list1.Count == 3); - - IListBlobItem item11 = list1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = list1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = list1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - List list2 = new List(); - do - { - BlobResultSegment result2 = midDir2.ListBlobsSegmentedAsync(true, BlobListingDetails.None, null, token, null, null).Result; - list2.AddRange(result2.Results); - token = result2.ContinuationToken; - } - while (token != null); - - Assert.IsTrue(list2.Count == 2); - - IListBlobItem item41 = list2.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = list2.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -#endif - - [TestMethod] - [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryFlatListingWithPrefix() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - container.Create(); - if (CloudBlobDirectorySetupWithDelimiter(container, delimiter)) - { - BlobContinuationToken token = null; - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1"); - List list1 = new List(); - do - { - BlobResultSegment result1 = directory.ListBlobsSegmented(token); - token = result1.ContinuationToken; - list1.AddRange(result1.Results); - } - while (token != null); - - Assert.IsTrue(list1.Count == 3); - - IListBlobItem item11 = list1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = list1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = list1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - List list2 = new List(); - do - { - BlobResultSegment result2 = midDir2.ListBlobsSegmented(true, BlobListingDetails.None, null, token, null, null); - token = result2.ContinuationToken; - list2.AddRange(result2.Results); - } - while (token != null); - - Assert.IsTrue(list2.Count == 2); - - IListBlobItem item41 = list2.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = list2.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Get subdirectory and then traverse back to parent")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetSubdirectoryAndTraverseBackToParent() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Get parent on root")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetParentOnRoot() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudBlobDirectory root = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory parent = root.Parent; - Assert.IsNull(parent); - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Check multiple delimiters")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryMultipleDelimiters() - { - foreach (String delimiter in Delimiters) - { - - CloudBlobClient client = GenerateCloudBlobClient(); - ////Set the default delimiter to \ - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - container.Create(); - if (CloudBlobDirectorySetupWithDelimiter(container, delimiter)) - { - IEnumerable list1 = container.ListBlobs("TopDir1" + delimiter, false, BlobListingDetails.None, null, null); - - List simpleList1 = list1.ToList(); - ////Check if for 3 because if there were more than 3, the previous assert would have failed. - ////So the only thing we need to make sure is that it is not less than 3. - Assert.IsTrue(simpleList1.Count == 3); - - IListBlobItem item11 = simpleList1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Hierarchical traversal")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryHierarchicalTraversal() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - ////Traverse hierarchically starting with length 1 - CloudBlobDirectory directory1 = container.GetDirectoryReference("Dir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("Dir2"); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("Dir3"); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - - CloudBlobDirectory subdir3 = subdir2.GetSubdirectoryReference("Dir4"); - CloudBlobDirectory parent3 = subdir3.Parent; - Assert.AreEqual(parent3.Prefix, subdir2.Prefix); - - CloudBlobDirectory subdir4 = subdir3.GetSubdirectoryReference("Dir5"); - CloudBlobDirectory parent4 = subdir4.Parent; - Assert.AreEqual(parent4.Prefix, subdir3.Prefix); - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Get directory parent for blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryBlobParentValidate() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - } - finally - { - container.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Validate CloudBlobDirectory in root container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryValidateInRootContainer() - { - foreach (String delimiter in Delimiters) - { - - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - CloudBlobContainer container = client.GetContainerReference("$root"); - - CloudPageBlob pageBlob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - if (delimiter == "/") - { - TestHelper.ExpectedException( - () => pageBlob.Create(0), - "Try to create a CloudBlobDirectory/blob which has a slash in its name in the root container", - HttpStatusCode.BadRequest); - } - - else - { - CloudPageBlob blob = container.GetPageBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - - CloudBlobDirectory directory1 = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("MidDir" + delimiter); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - Assert.AreEqual(parent1.Uri, directory1.Uri); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("EndDir" + delimiter); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - Assert.AreEqual(parent2.Uri, subdir1.Uri); - } - } - } - - [TestMethod] - [Description("Multiple delimiters in a row or empty directory names")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryDelimitersInARow() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudPageBlob blob = container.GetPageBlobReference(delimiter+delimiter+delimiter+"Blob1"); - - ////Traverse from leaf to root - CloudBlobDirectory directory1 = blob.Parent; - Assert.AreEqual(directory1.Prefix, delimiter+delimiter+delimiter); - - CloudBlobDirectory directory2 = directory1.Parent; - Assert.AreEqual(directory2.Prefix, delimiter+delimiter); - - CloudBlobDirectory directory3 = directory2.Parent; - Assert.AreEqual(directory3.Prefix, delimiter); - - ////Traverse from root to leaf - CloudBlobDirectory directory4 = container.GetDirectoryReference(delimiter); - CloudBlobDirectory directory5 = directory4.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory5.Prefix, delimiter+delimiter); - - CloudBlobDirectory directory6 = directory5.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory6.Prefix, delimiter+delimiter+delimiter); - - CloudPageBlob blob2 = directory6.GetPageBlobReference("Blob1"); - Assert.AreEqual(blob2.Name, delimiter+delimiter+delimiter+"Blob1"); - Assert.AreEqual(blob2.Uri, blob.Uri); - } - finally - { - container.DeleteIfExists(); - } - } - } - - - } -} - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlockBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlockBlobTest.cs deleted file mode 100644 index 612b17994a9ab..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudBlockBlobTest.cs +++ /dev/null @@ -1,3513 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Security.Cryptography; -using System.Text; -using System.Threading; -using System.Xml; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlockBlobTest : BlobTestBase - { - private static void CreateForTest(CloudBlockBlob blob, int blockCount, int blockSize, bool isAsync, bool commit = true) - { - byte[] buffer = GetRandomBuffer(blockSize); - List blocks = GetBlockIdList(blockCount); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - foreach (string block in blocks) - { - using (MemoryStream stream = new MemoryStream(buffer)) - { - if (isAsync) - { - IAsyncResult result = blob.BeginPutBlock(block, stream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - } - else - { - blob.PutBlock(block, stream, null); - } - } - } - - if (commit) - { - if (isAsync) - { - IAsyncResult result = blob.BeginPutBlockList(blocks, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlockList(result); - } - else - { - blob.PutBlockList(blocks); - } - } - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - -#if TASK - private static void CreateForTestTask(CloudBlockBlob blob, int blockCount, int blockSize, bool commit = true) - { - byte[] buffer = GetRandomBuffer(blockSize); - List blocks = GetBlockIdList(blockCount); - - foreach (string block in blocks) - { - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(block, stream, null, null, null, null).Wait(); - } - } - - if (commit) - { - blob.PutBlockListAsync(blocks, null, null, null).Wait(); - } - } -#endif - - [TestMethod] - [Description("Get a block blob reference using its constructor")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobConstructor() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 0, 0, false); - - CloudBlockBlob blob2 = new CloudBlockBlob(blob.Uri); - Assert.AreEqual(blob.Uri, blob2.Uri); - Assert.AreEqual(blob.Name, blob2.Name); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a zero-length block blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCreateAndDelete() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 0, 0, false); - Assert.IsTrue(blob.Exists()); - blob.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a zero-length block blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCreateAndDeleteAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 0, 0, false); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(blob.EndExists(result)); - result = blob.BeginDelete(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndDelete(result); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a zero-length block blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCreateAndDeleteTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.PutBlockListAsync(new List()).Wait(); - Assert.IsTrue(blob.ExistsAsync().Result); - blob.DeleteAsync().Wait(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Try to delete a non-existing block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDeleteIfExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - Assert.IsFalse(blob.DeleteIfExists()); - CreateForTest(blob, 0, 0, false); - Assert.IsTrue(blob.DeleteIfExists()); - Assert.IsFalse(blob.DeleteIfExists()); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDeleteIfExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - IAsyncResult result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob.EndDeleteIfExists(result)); - CreateForTest(blob, 0, 0, true); - result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(blob.EndDeleteIfExists(result)); - result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob.EndDeleteIfExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Try to delete a non-existing block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDeleteIfExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - Assert.IsFalse(blob.DeleteIfExistsAsync().Result); - blob.PutBlockListAsync(new List()).Wait(); - Assert.IsTrue(blob.DeleteIfExistsAsync().Result); - Assert.IsFalse(blob.DeleteIfExistsAsync().Result); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - - Assert.IsFalse(blob2.Exists()); - - CreateForTest(blob, 2, 1024, false); - - Assert.IsTrue(blob2.Exists()); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.Delete(); - - Assert.IsFalse(blob2.Exists()); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob2.EndExists(result)); - - CreateForTest(blob, 2, 1024, false); - - result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(blob2.EndExists(result)); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.Delete(); - - result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob2.EndExists(result)); - } - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - - Assert.IsFalse(blob2.ExistsAsync().Result); - - CreateForTestTask(blob, 2, 1024); - - Assert.IsTrue(blob2.ExistsAsync().Result); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.DeleteAsync().Wait(); - - Assert.IsFalse(blob2.ExistsAsync().Result); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobFetchAttributes() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, false); - Assert.AreEqual(-1, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob.Properties.BlobType); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobFetchAttributesAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, true); - Assert.AreEqual(-1, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob.Properties.BlobType); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - IAsyncResult result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - } - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobFetchAttributesTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTestTask(blob, 1, 1024); - Assert.AreEqual(-1, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob.Properties.BlobType); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetProperties() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, false); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - blob.SetProperties(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudBlockBlob blob3 = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - blob3.DownloadToStream(stream, null, options); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - CloudBlockBlob blob4 = (CloudBlockBlob)container.ListBlobs().First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetPropertiesAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, true); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - IAsyncResult result = blob.BeginSetProperties( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetProperties(result); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudBlockBlob blob3 = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - result = blob3.BeginDownloadToStream(stream, null, options, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob3.EndDownloadToStream(result); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - result = container.BeginListBlobsSegmented(null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - CloudBlockBlob blob4 = (CloudBlockBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetPropertiesTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTestTask(blob, 1, 1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - blob.SetPropertiesAsync().Wait(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudBlockBlob blob3 = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - blob3.DownloadToStreamAsync(stream, null, options, null).Wait(); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - CloudBlockBlob blob4 = (CloudBlockBlob)container.ListBlobsSegmentedAsync(null).Result.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Try retrieving properties of a block blob using a page blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobFetchAttributesInvalidType() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, false); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - StorageException e = TestHelper.ExpectedException( - () => blob2.FetchAttributes(), - "Fetching attributes of a block blob using a page blob reference should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that creating a block blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCreateWithMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - CreateForTest(blob, 0, 0, false); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that a block blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 0, 0, false); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - StorageException e = TestHelper.ExpectedException( - () => blob.SetMetadata(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - e = TestHelper.ExpectedException( - () => blob.SetMetadata(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - blob.SetMetadata(); - - blob2.FetchAttributes(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - CloudBlockBlob blob3 = (CloudBlockBlob)container.ListBlobs(null, true, BlobListingDetails.Metadata, null, null).First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - blob.SetMetadata(); - - blob2.FetchAttributes(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that a block blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetMetadataAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 0, 0, true); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - IAsyncResult result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Exception e = TestHelper.ExpectedException( - () => blob.EndSetMetadata(result), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - e = TestHelper.ExpectedException( - () => blob.EndSetMetadata(result), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetMetadata(result); - - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - result = container.BeginListBlobsSegmented(null, true, BlobListingDetails.Metadata, null, null, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - CloudBlockBlob blob3 = (CloudBlockBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetMetadata(result); - - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(0, blob2.Metadata.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify that a block blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSetMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTestTask(blob, 0, 0); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - StorageException e = TestHelper.ExpectedExceptionTask( - blob.SetMetadataAsync(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - e = TestHelper.ExpectedExceptionTask( - blob.SetMetadataAsync(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - blob.SetMetadataAsync().Wait(); - - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - CloudBlockBlob blob3 = - (CloudBlockBlob) - container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null) - .Result - .Results - .First(); - - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - blob.SetMetadataAsync().Wait(); - - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload blocks and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUpload() - { - CloudBlockBlobUpload(true, false); - } - - [TestMethod] - [Description("Upload blocks with non-seekable stream and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadWithNonSeekableStream() - { - CloudBlockBlobUpload(false, false); - } - - [TestMethod] - [Description("Upload blocks and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadAPM() - { - CloudBlockBlobUpload(true, true); - } - - [TestMethod] - [Description("Upload blocks with non-seekable stream and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadWithNonSeekableStreamAPM() - { - CloudBlockBlobUpload(false, true); - } - - private void CloudBlockBlobUpload(bool seekableSourceStream, bool isAsync) - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (MemoryStream wholeBlob = new MemoryStream()) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - foreach (string block in blocks) - { - using (Stream memoryStream = seekableSourceStream ? new MemoryStream(buffer) : new NonSeekableMemoryStream(buffer)) - { - if (isAsync) - { - IAsyncResult result = blob.BeginPutBlock(block, memoryStream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - } - else - { - blob.PutBlock(block, memoryStream, null); - } - } - wholeBlob.Write(buffer, 0, buffer.Length); - } - - foreach (string block in extraBlocks) - { - using (Stream memoryStream = seekableSourceStream ? new MemoryStream(buffer) : new NonSeekableMemoryStream(buffer)) - { - if (isAsync) - { - IAsyncResult result = blob.BeginPutBlock(block, memoryStream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - } - else - { - blob.PutBlock(block, memoryStream, null); - } - } - } - - if (isAsync) - { - IAsyncResult result = blob.BeginPutBlockList(blocks, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlockList(result); - } - else - { - blob.PutBlockList(blocks); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob2.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Upload blocks and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadTask() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - using (MemoryStream wholeBlob = new MemoryStream()) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (Stream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(block, memoryStream, null).Wait(); - } - wholeBlob.Write(buffer, 0, buffer.Length); - } - - foreach (string block in extraBlocks) - { - using (Stream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(block, memoryStream, null).Wait(); - } - } - blob.PutBlockListAsync(blocks).Wait(); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob2.DownloadToStreamAsync(downloadedBlob).Wait(); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload a block blob and then verify the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadBlockList() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlock(block, memoryStream, null); - } - } - blob.PutBlockList(blocks); - - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlock(block, memoryStream, null); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1024 * blocks.Count, blob2.Properties.Length); - - IEnumerable blockList = blob2.DownloadBlockList(); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsTrue(blockItem.Committed); - Assert.IsTrue(blocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, blocks.Count); - - blockList = blob2.DownloadBlockList(BlockListingFilter.Uncommitted, null, null, null); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsFalse(blockItem.Committed); - Assert.IsTrue(extraBlocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, extraBlocks.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload a block blob and then verify the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadBlockListAPM() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlock(block, memoryStream, null); - } - } - blob.PutBlockList(blocks); - - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlock(block, memoryStream, null); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1024 * blocks.Count, blob2.Properties.Length); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob2.BeginDownloadBlockList( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - IEnumerable blockList = blob2.EndDownloadBlockList(result); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsTrue(blockItem.Committed); - Assert.IsTrue(blocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, blocks.Count); - - result = blob2.BeginDownloadBlockList(BlockListingFilter.Uncommitted, null, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockList = blob2.EndDownloadBlockList(result); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsFalse(blockItem.Committed); - Assert.IsTrue(extraBlocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, extraBlocks.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Upload a block blob and then verify the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadBlockListTask() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(block, memoryStream, null).Wait(); - } - } - blob.PutBlockListAsync(blocks).Wait(); - - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(block, memoryStream, null).Wait(); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1024 * blocks.Count, blob2.Properties.Length); - - IEnumerable blockList = blob2.DownloadBlockListAsync().Result; - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsTrue(blockItem.Committed); - Assert.IsTrue(blocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, blocks.Count); - - blockList = blob2.DownloadBlockListAsync(BlockListingFilter.Uncommitted, null, null, null).Result; - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsFalse(blockItem.Committed); - Assert.IsTrue(extraBlocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, extraBlocks.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStream() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - blob.UploadFromStream(originalBlob); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStream(downloadedBlob); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamAPM() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - result = blob.BeginDownloadToStream(downloadedBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamAPMOverload() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext context = new OperationContext(); - result = blob.BeginDownloadRangeToStream(downloadedBlob, - 0, /* offset */ - buffer.Length, /* Length */ - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadRangeToStream(result); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamTask() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(originalBlob).Wait(); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStreamAsync(downloadedBlob).Wait(); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobDownloadToStreamOverloadTask() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(originalBlob).Wait(); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext context = new OperationContext(); - blob.DownloadRangeToStreamAsync(downloadedBlob, 0, buffer.Length).Wait(); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync(); - } - } -#endif - - [TestMethod] - [Description("Single put blob with invalid options")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamInvalidOptions() - { - BlobRequestOptions options = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - StoreBlobContentMD5 = false, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.UploadFromStream(stream, null, options, null), - "Single put blob with mismatching MD5 options should fail immediately"); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Single put blob with invalid options")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamAPMInvalidOptions() - { - BlobRequestOptions options = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - StoreBlobContentMD5 = false, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.BeginUploadFromStream(stream, null, options, null, null, null), - "Single put blob with mismatching MD5 options should fail immediately"); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob with invalid options")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamInvalidOptionsTask() - { - BlobRequestOptions options = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - StoreBlobContentMD5 = false, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.UploadFromStreamAsync(stream, null, options, null), - "Single put blob with mismatching MD5 options should fail immediately"); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, false, true); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, false); - blob.FetchAttributes(); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, false, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, false, true); - - blob = container.GetBlockBlobReference("blob3"); - CreateForTest(blob, 1, 1024, false); - blob.FetchAttributes(); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, false, true), - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, false, true), - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.NotFound); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamAPMWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, true, true); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 1, 1024, false); - blob.FetchAttributes(); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, true, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, true, true); - - blob = container.GetBlockBlobReference("blob3"); - CreateForTest(blob, 1, 1024, false); - blob.FetchAttributes(); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, true, true), - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - TestHelper.ExpectedException( - () => this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, true, true), - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.NotFound); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 2 * 1024 * 1024, null, accessCondition, true, false, 0, true, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamWithNonSeekableStream() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, true, 1024, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, false, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamAPMWithNonSeekableStream() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, true, 1024, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, false, false, 1024, true, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStream() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, true, 1024, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, false, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, true, 1024, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, null, null, true, false, 1024, true, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamLength() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - // Upload 2MB of a 5MB stream - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, true, 1024, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, false, 1024, false, true); - - // Exclude last byte - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, true, true, 1024, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, true, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, true, false, 1024, false, true); - - // Upload exact amount - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, true, true, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, true, true, 1024, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, true, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, true, false, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamLengthAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - // Upload 2MB of a 5MB stream - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, true, 1024, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, true, false, 1024, true, true); - - // Exclude last byte - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, true, true, 1024, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, true, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, true, false, 1024, true, true); - - // Upload exact amount - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, true, true, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, true, true, 1024, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, true, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, true, false, 1024, true, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamLengthInvalid() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, true, true, 0, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, true, true, 1024, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, false, true, 0, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, false, true, 1024, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, true, false, 0, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, true, false, 1024, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, false, false, 0, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, false, false, 1024, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadFromStreamLengthInvalidAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, true, true, 0, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, true, true, 1024, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, false, true, 0, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, false, true, 1024, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, true, false, 0, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, true, false, 1024, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, false, false, 0, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => - this.CloudBlockBlobUploadFromStream( - container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, false, false, 1024, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Upload blob using multiple threads and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobParallelUploadFromStream() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 8; - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 16 * 1024 * 1024, null, null, true, false, 0, false, true); - this.CloudBlockBlobUploadFromStream(container, 16 * 1024 * 1024, null, null, true, false, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Upload blob using multiple threads and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobParallelUploadFromStreamAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 8; - container.Create(); - try - { - this.CloudBlockBlobUploadFromStream(container, 16 * 1024 * 1024, null, null, true, false, 0, true, true); - this.CloudBlockBlobUploadFromStream(container, 16 * 1024 * 1024, null, null, true, false, 1024, true, true); - } - finally - { - container.Delete(); - } - } - - private void CloudBlockBlobUploadFromStream(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, bool seekableSourceStream, bool allowSinglePut, int startOffset, bool isAsync, bool testMd5) - { - byte[] buffer = GetRandomBuffer(size); - - MD5 hasher = MD5.Create(); - - string md5 = string.Empty; - if (testMd5) - { - md5 = Convert.ToBase64String(hasher.ComputeHash(buffer, startOffset, copyLength.HasValue ? (int)copyLength : buffer.Length - startOffset)); - } - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.ServiceClient.SingleBlobUploadThresholdInBytes = allowSinglePut ? buffer.Length : buffer.Length / 2; - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - - using (MemoryStream originalBlobStream = new MemoryStream()) - { - originalBlobStream.Write(buffer, startOffset, buffer.Length - startOffset); - - Stream sourceStream; - if (seekableSourceStream) - { - MemoryStream stream = new MemoryStream(buffer); - stream.Seek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - else - { - NonSeekableMemoryStream stream = new NonSeekableMemoryStream(buffer); - stream.ForceSeek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - - using (sourceStream) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - if (isAsync) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - if (copyLength.HasValue) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream( - sourceStream, copyLength.Value, accessCondition, options, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - else - { - ICancellableAsyncResult result = blob.BeginUploadFromStream( - sourceStream, accessCondition, options, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - } - } - else - { - if (copyLength.HasValue) - { - blob.UploadFromStream(sourceStream, copyLength.Value, accessCondition, options); - } - else - { - blob.UploadFromStream(sourceStream, accessCondition, options); - } - } - } - - blob.FetchAttributes(); - - if (testMd5) - { - Assert.AreEqual(md5, blob.Properties.ContentMD5); - } - - using (MemoryStream downloadedBlobStream = new MemoryStream()) - { - if (isAsync) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginDownloadToStream( - downloadedBlobStream, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - } - } - else - { - blob.DownloadToStream(downloadedBlobStream); - } - - Assert.AreEqual(copyLength ?? originalBlobStream.Length, downloadedBlobStream.Length); - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlobStream, - downloadedBlobStream, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlobStream.Length); - } - } - - blob.Delete(); - } - - [TestMethod] - [Description("Create snapshots of a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshot() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.UploadFromStream(originalData); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudBlockBlob snapshot1 = blob.CreateSnapshot(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudBlockBlob snapshot2 = blob.CreateSnapshot(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributes(); - snapshot2.FetchAttributes(); - blob.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudBlockBlob snapshot1Clone = new CloudBlockBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - snapshot1Clone.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudBlockBlob snapshotCopy = container.GetBlockBlobReference("blob2"); - snapshotCopy.StartCopyFromBlob(TestHelper.Defiddler(snapshot1.Uri)); - WaitForCopy(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.OpenWrite(), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = snapshot1.OpenRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - blob.PutBlockList(new List()); - blob.FetchAttributes(); - - using (Stream snapshotStream = snapshot1.OpenRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create snapshots of a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshotAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginUploadFromStream(originalData, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - result = blob.BeginCreateSnapshot(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudBlockBlob snapshot1 = blob.EndCreateSnapshot(result); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - result = blob.BeginCreateSnapshot(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudBlockBlob snapshot2 = blob.EndCreateSnapshot(result); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributes(); - snapshot2.FetchAttributes(); - blob.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudBlockBlob snapshotCopy = container.GetBlockBlobReference("blob2"); - result = snapshotCopy.BeginStartCopyFromBlob(snapshot1, null, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - snapshotCopy.EndStartCopyFromBlob(result); - WaitForCopy(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.BeginOpenWrite(ar => waitHandle.Set(), null), - "Trying to write to a blob snapshot should fail"); - - TestHelper.ExpectedException( - () => snapshot2.BeginOpenWrite(null, null, null, ar => waitHandle.Set(), null), - "Trying to write to a blob snapshot should fail"); - - result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - using (Stream snapshotStream = snapshot1.EndOpenRead(result)) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - result = blob.BeginPutBlockList(new List(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndPutBlockList(result); - - result = blob.BeginFetchAttributes(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndFetchAttributes(result); - - result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - using (Stream snapshotStream = snapshot1.EndOpenRead(result)) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create snapshots of a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshotTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - blob.UploadFromStreamAsync(originalData).Wait(); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudBlockBlob snapshot1 = blob.CreateSnapshotAsync().Result; - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudBlockBlob snapshot2 = blob.CreateSnapshotAsync().Result; - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributesAsync().Wait(); - snapshot2.FetchAttributesAsync().Wait(); - blob.FetchAttributesAsync().Wait(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudBlockBlob snapshotCopy = container.GetBlockBlobReference("blob2"); - snapshotCopy.StartCopyFromBlobAsync(snapshot1, null, null, null, null).Wait(); - bool copyInProgress = true; - while (copyInProgress) - { - Thread.Sleep(1000); - snapshotCopy.FetchAttributesAsync().Wait(); - copyInProgress = (snapshotCopy.CopyState.Status == CopyStatus.Pending); - } - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.OpenWriteAsync(), - "Trying to write to a blob snapshot should fail"); - - TestHelper.ExpectedException( - () => snapshot2.OpenWriteAsync(null, null, null), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - blob.PutBlockListAsync(new List()).Wait(); - - blob.FetchAttributesAsync().Wait(); - - using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = - container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null) - .Result - .Results - .ToList(); - - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshotMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 2, 1024, false); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadata(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudBlockBlob snapshot = blob.CreateSnapshot(snapshotMetadata); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributes(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshotMetadataAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 2, 1024, false); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadata(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - OperationContext context = new OperationContext(); - result = blob.BeginCreateSnapshot(snapshotMetadata, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudBlockBlob snapshot = blob.EndCreateSnapshot(result); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributes(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSnapshotMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTestTask(blob, 2, 1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadataAsync().Wait(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudBlockBlob snapshot = blob.CreateSnapshotAsync(snapshotMetadata, null, null, null).Result; - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributesAsync().Wait(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobConditionalAccess() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CreateForTest(blob, 2, 1024, false); - blob.FetchAttributes(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - blob.SetMetadata(AccessCondition.GenerateIfMatchCondition(currentETag), null); - - blob.FetchAttributes(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNoneMatchCondition(newETag), null), - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfMatchCondition(invalidETag), null), - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - blob.SetMetadata(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null); - - blob.FetchAttributes(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null), - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null); - - blob.FetchAttributes(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Put block boundaries")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobPutBlockBoundaries() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - string blockId = GetBlockIdList(1).First(); - - byte[] buffer = new byte[0]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - TestHelper.ExpectedException( - () => blob.PutBlock(blockId, stream, null), - "Trying to upload a block with zero bytes should fail", - HttpStatusCode.BadRequest); - } - - buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlock(blockId, stream, null); - } - - buffer = new byte[4 * 1024 * 1024]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlock(blockId, stream, null); - } - - buffer = new byte[4 * 1024 * 1024 + 1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - TestHelper.ExpectedException( - () => blob.PutBlock(blockId, stream, null), - "Trying to upload a block with more than 4MB should fail", - HttpStatusCode.RequestEntityTooLarge); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Put block boundaries")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobPutBlockBoundariesAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - string blockId = GetBlockIdList(1).First(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - byte[] buffer = new byte[0]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - result = blob.BeginPutBlock(blockId, stream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndPutBlock(result), - "Trying to upload a block with zero bytes should fail", - HttpStatusCode.BadRequest); - } - - buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - result = blob.BeginPutBlock(blockId, stream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - } - - buffer = new byte[4 * 1024 * 1024]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - result = blob.BeginPutBlock(blockId, stream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - } - - buffer = new byte[4 * 1024 * 1024 + 1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - result = blob.BeginPutBlock(blockId, stream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndPutBlock(result), - "Trying to upload a block with more than 4MB should fail", - HttpStatusCode.RequestEntityTooLarge); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Put block boundaries")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobPutBlockBoundariesTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - string blockId = GetBlockIdList(1).First(); - - byte[] buffer = new byte[0]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - TestHelper.ExpectedExceptionTask( - blob.PutBlockAsync(blockId, stream, null), - "Trying to upload a block with zero bytes should fail", - HttpStatusCode.BadRequest); - } - - buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(blockId, stream, null).Wait(); - } - - buffer = new byte[4 * 1024 * 1024]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlockAsync(blockId, stream, null).Wait(); - } - - buffer = new byte[4 * 1024 * 1024 + 1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - TestHelper.ExpectedExceptionTask( - blob.PutBlockAsync(blockId, stream, null), - "Trying to upload a block with more than 4MB should fail", - HttpStatusCode.RequestEntityTooLarge); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload blocks and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobPutBlock() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - List blockList = GetBlockIdList(2); - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - memoryStream.Seek(0, SeekOrigin.Begin); - blob.PutBlock(blockList[0], memoryStream, contentMD5); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - TestHelper.ExpectedException( - () => blob.PutBlock(blockList[1], memoryStream, contentMD5), - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - blob.PutBlock(blockList[1], memoryStream, null); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - blob.PutBlockList(blockList); - - using (MemoryStream blobData = new MemoryStream()) - { - blob.DownloadToStream(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload blocks and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobPutBlockAPM() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - List blockList = GetBlockIdList(2); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - memoryStream.Seek(0, SeekOrigin.Begin); - result = blob.BeginPutBlock(blockList[0], memoryStream, contentMD5, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - result = blob.BeginPutBlock(blockList[1], memoryStream, contentMD5, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndPutBlock(result), - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - result = blob.BeginPutBlock(blockList[1], memoryStream, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndPutBlock(result); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - blob.PutBlockList(blockList); - - using (MemoryStream blobData = new MemoryStream()) - { - blob.DownloadToStream(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test block blob methods on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobMethodsOnPageBlob() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - List blobs = CreateBlobs(container, 1, BlobType.PageBlob); - CloudBlockBlob blob = container.GetBlockBlobReference(blobs.First()); - List blockList = GetBlockIdList(1); - - byte[] buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - TestHelper.ExpectedException( - () => blob.PutBlock(blockList.First(), stream, null), - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - TestHelper.ExpectedException( - () => blob.PutBlockList(blockList), - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - TestHelper.ExpectedException( - () => blob.DownloadBlockList(), - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test block removal/addition/reordering in a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobBlockReordering() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - List originalBlockIds = GetBlockIdList(10); - List blockIds = new List(originalBlockIds); - List blocks = new List(); - for (int i = 0; i < blockIds.Count; i++) - { - byte[] buffer = Encoding.UTF8.GetBytes(i.ToString()); - using (MemoryStream stream = new MemoryStream(buffer)) - { - blob.PutBlock(blockIds[i], stream, null); - } - blocks.Add(buffer); - } - blob.PutBlockList(blockIds); - Assert.AreEqual("0123456789", DownloadText(blob, Encoding.UTF8)); - - blockIds.RemoveAt(0); - blob.PutBlockList(blockIds); - Assert.AreEqual("123456789", DownloadText(blob, Encoding.UTF8)); - - blockIds.RemoveAt(8); - blob.PutBlockList(blockIds); - Assert.AreEqual("12345678", DownloadText(blob, Encoding.UTF8)); - - blockIds.RemoveAt(3); - blob.PutBlockList(blockIds); - Assert.AreEqual("1235678", DownloadText(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[9])) - { - blob.PutBlock(originalBlockIds[9], stream, null); - } - blockIds.Insert(0, originalBlockIds[9]); - blob.PutBlockList(blockIds); - Assert.AreEqual("91235678", DownloadText(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[0])) - { - blob.PutBlock(originalBlockIds[0], stream, null); - } - blockIds.Add(originalBlockIds[0]); - blob.PutBlockList(blockIds); - Assert.AreEqual("912356780", DownloadText(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[4])) - { - blob.PutBlock(originalBlockIds[4], stream, null); - } - blockIds.Insert(2, originalBlockIds[4]); - blob.PutBlockList(blockIds); - Assert.AreEqual("9142356780", DownloadText(blob, Encoding.UTF8)); - - blockIds.Insert(0, originalBlockIds[0]); - blob.PutBlockList(blockIds); - Assert.AreEqual("09142356780", DownloadText(blob, Encoding.UTF8)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadDownloadNoData() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob"); - TestHelper.ExpectedException( - () => blob.UploadFromStream(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - blob.UploadFromStream(stream); - } - - TestHelper.ExpectedException( - () => blob.DownloadToStream(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - blob.DownloadToStream(stream); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("List committed and uncommitted blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobListUncommittedBlobs() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - List committedBlobs = new List(); - for (int i = 0; i < 3; i++) - { - string name = "cblob" + i.ToString(); - CloudBlockBlob committedBlob = container.GetBlockBlobReference(name); - CreateForTest(committedBlob, 2, 1024, false); - committedBlobs.Add(name); - } - - List uncommittedBlobs = new List(); - for (int i = 0; i < 5; i++) - { - string name = "ucblob" + i.ToString(); - CloudBlockBlob uncommittedBlob = container.GetBlockBlobReference(name); - CreateForTest(uncommittedBlob, 2, 1024, false, false); - uncommittedBlobs.Add(name); - } - - List blobs = container.ListBlobs(null, true, BlobListingDetails.UncommittedBlobs).ToList(); - foreach (ICloudBlob blob in blobs) - { - if (committedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(2 * 1024, blob.Properties.Length); - } - else if (uncommittedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(0, blob.Properties.Length); - } - else - { - Assert.Fail("Blob is not found in either committed or uncommitted list"); - } - } - - Assert.AreEqual(0, committedBlobs.Count); - Assert.AreEqual(0, uncommittedBlobs.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try operations with an invalid Sas and snapshot")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobInvalidSasAndSnapshot() - { - // Sas token creds. - string token = "?sp=abcde&sig=1"; - StorageCredentials creds = new StorageCredentials(token); - Assert.IsTrue(creds.IsSAS); - - // Client with shared key access. - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(GetRandomContainerName()); - try - { - container.Create(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, - }; - string sasToken = container.GetSharedAccessSignature(policy); - - string blobUri = container.Uri.AbsoluteUri + "/blob1" + sasToken; - TestHelper.ExpectedException( - () => new CloudBlockBlob(new Uri(blobUri), container.ServiceClient.Credentials), - "Try to use SAS creds in Uri on a shared key client"); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.UploadFromStream(new MemoryStream(GetRandomBuffer(10))); - - CloudBlockBlob snapshot = blob.CreateSnapshot(); - DateTimeOffset? wrongTime = snapshot.SnapshotTime.Value + TimeSpan.FromSeconds(10); - - string snapshotUri = snapshot.Uri + "?snapshot=" + wrongTime.Value.ToString(); - TestHelper.ExpectedException( - () => new CloudBlockBlob(new Uri(snapshotUri), snapshot.SnapshotTime, container.ServiceClient.Credentials), - "Snapshot in Uri does not match snapshot on blob"); - - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload and download text")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadText() - { - this.DoTextUploadDownload("test", false, false); - this.DoTextUploadDownload("char中文test", true, false); - this.DoTextUploadDownload("", false, false); - } - - [TestMethod] - [Description("Upload and download text")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadTextAPM() - { - this.DoTextUploadDownload("test", false, true); - this.DoTextUploadDownload("char中文test", true, true); - this.DoTextUploadDownload("", false, true); - } - -#if TASK - [TestMethod] - [Description("Upload and download text")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobUploadTextTask() - { - this.DoTextUploadDownloadTask("test", false); - this.DoTextUploadDownloadTask("char中文test", true); - this.DoTextUploadDownloadTask("", false); - } -#endif - - private void DoTextUploadDownload(string text, bool checkDifferentEncoding, bool isAsync) - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateIfNotExists(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - if (isAsync) - { - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginUploadText(text, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadText(result); - result = blob.BeginDownloadText( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.AreEqual(text, blob.EndDownloadText(result)); - if (checkDifferentEncoding) - { - result = blob.BeginDownloadText(Encoding.Unicode, null, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.AreNotEqual(text, blob.EndDownloadText(result)); - } - - OperationContext context = new OperationContext(); - result = blob.BeginUploadText(text, Encoding.Unicode, null, null, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadText(result); - Assert.AreEqual(1, context.RequestResults.Count); - result = blob.BeginDownloadText(Encoding.Unicode, null, null, context, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.AreEqual(text, blob.EndDownloadText(result)); - Assert.AreEqual(2, context.RequestResults.Count); - if (checkDifferentEncoding) - { - result = blob.BeginDownloadText( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.AreNotEqual(text, blob.EndDownloadText(result)); - } - } - } - else - { - blob.UploadText(text); - Assert.AreEqual(text, blob.DownloadText()); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, blob.DownloadText(Encoding.Unicode)); - } - - blob.UploadText(text, Encoding.Unicode); - Assert.AreEqual(text, blob.DownloadText(Encoding.Unicode)); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, blob.DownloadText()); - } - - OperationContext context = new OperationContext(); - blob.UploadText(text, Encoding.Unicode, null, null, context); - Assert.AreEqual(1, context.RequestResults.Count); - blob.DownloadText(Encoding.Unicode, null, null, context); - Assert.AreEqual(2, context.RequestResults.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - private void DoTextUploadDownloadTask(string text, bool checkDifferentEncoding) - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateIfNotExistsAsync().Wait(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - blob.UploadTextAsync(text).Wait(); - Assert.AreEqual(text, blob.DownloadTextAsync().Result); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, blob.DownloadTextAsync(Encoding.Unicode, null, null, null).Result); - } - - blob.UploadTextAsync(text, Encoding.Unicode, null, null, null).Wait(); - Assert.AreEqual(text, blob.DownloadTextAsync(Encoding.Unicode, null, null, null).Result); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, blob.DownloadTextAsync().Result); - } - - OperationContext context = new OperationContext(); - blob.UploadTextAsync(text, Encoding.Unicode, null, null, context).Wait(); - Assert.AreEqual(1, context.RequestResults.Count); - blob.DownloadTextAsync(Encoding.Unicode, null, null, context).Wait(); - Assert.AreEqual(2, context.RequestResults.Count); - } - finally - { - container.DeleteIfExists(); - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudPageBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudPageBlobTest.cs deleted file mode 100644 index adce9f78ec649..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CloudPageBlobTest.cs +++ /dev/null @@ -1,3469 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Security.Cryptography; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudPageBlobTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a zero-length page blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCreateAndDelete() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(0); - Assert.IsTrue(blob.Exists()); - blob.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a zero-length page blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCreateAndDeleteAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - IAsyncResult result; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - result = blob.BeginCreate(0, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndCreate(result); - - result = blob.BeginExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(blob.EndExists(result)); - - result = blob.BeginDelete(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndDelete(result); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a zero-length page blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCreateAndDeleteTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(0).Wait(); - Assert.IsTrue(blob.ExistsAsync().Result); - blob.DeleteAsync().Wait(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Get a page blob reference using its constructor")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobConstructor() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(0); - - CloudPageBlob blob2 = new CloudPageBlob(blob.Uri); - Assert.AreEqual(blob.Uri, blob2.Uri); - Assert.AreEqual(blob.Name, blob2.Name); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Resize a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobResize() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - blob.Create(1024); - Assert.AreEqual(1024, blob.Properties.Length); - blob2.FetchAttributes(); - Assert.AreEqual(1024, blob2.Properties.Length); - blob2.Properties.ContentType = "text/plain"; - blob2.SetProperties(); - blob.Resize(2048); - Assert.AreEqual(2048, blob.Properties.Length); - blob.FetchAttributes(); - Assert.AreEqual("text/plain", blob.Properties.ContentType); - blob2.FetchAttributes(); - Assert.AreEqual(2048, blob2.Properties.Length); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Resize a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobResizeAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginCreate(1024, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndCreate(result); - Assert.AreEqual(1024, blob.Properties.Length); - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - blob2.Properties.ContentType = "text/plain"; - result = blob2.BeginSetProperties( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndSetProperties(result); - Assert.AreEqual(1024, blob2.Properties.Length); - result = blob.BeginResize(2048, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndResize(result); - Assert.AreEqual(2048, blob.Properties.Length); - result = blob.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndFetchAttributes(result); - Assert.AreEqual("text/plain", blob.Properties.ContentType); - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(2048, blob2.Properties.Length); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Resize a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobResizeTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - blob.CreateAsync(1024).Wait(); - Assert.AreEqual(1024, blob.Properties.Length); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1024, blob2.Properties.Length); - blob2.Properties.ContentType = "text/plain"; - blob2.SetPropertiesAsync().Wait(); - blob.ResizeAsync(2048).Wait(); - Assert.AreEqual(2048, blob.Properties.Length); - blob.FetchAttributesAsync().Wait(); - Assert.AreEqual("text/plain", blob.Properties.ContentType); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(2048, blob2.Properties.Length); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Use sequence number conditions on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSequenceNumber() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - blob.Create(buffer.Length); - Assert.IsNull(blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumber(SequenceNumberAction.Update, 5); - Assert.AreEqual(5, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumber(SequenceNumberAction.Max, 7); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumber(SequenceNumberAction.Max, 3); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumber(SequenceNumberAction.Increment, null); - Assert.AreEqual(8, blob.Properties.PageBlobSequenceNumber); - - StorageException e = TestHelper.ExpectedException( - () => blob.SetSequenceNumber(SequenceNumberAction.Update, null), - "SetSequenceNumber with Update should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = TestHelper.ExpectedException( - () => blob.SetSequenceNumber(SequenceNumberAction.Update, -1), - "Negative sequence numbers are not supported"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentOutOfRangeException)); - - e = TestHelper.ExpectedException( - () => blob.SetSequenceNumber(SequenceNumberAction.Max, null), - "SetSequenceNumber with Max should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = TestHelper.ExpectedException( - () => blob.SetSequenceNumber(SequenceNumberAction.Increment, 1), - "SetSequenceNumber with Increment should require null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - using (MemoryStream stream = new MemoryStream(buffer)) - { - stream.Seek(0, SeekOrigin.Begin); - blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedException( - () => blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedException( - () => blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedException( - () => blob.ClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Use sequence number conditions on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSequenceNumberAPM() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginCreate(buffer.Length, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndCreate(result); - Assert.IsNull(blob.Properties.PageBlobSequenceNumber); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Update, 5, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetSequenceNumber(result); - Assert.AreEqual(5, blob.Properties.PageBlobSequenceNumber); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Max, 7, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetSequenceNumber(result); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Max, 3, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetSequenceNumber(result); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Increment, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetSequenceNumber(result); - Assert.AreEqual(8, blob.Properties.PageBlobSequenceNumber); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Update, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - StorageException e = TestHelper.ExpectedException( - () => blob.EndSetSequenceNumber(result), - "SetSequenceNumber with Update should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Update, -1, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - e = TestHelper.ExpectedException( - () => blob.EndSetSequenceNumber(result), - "Negative sequence numbers are not supported"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentOutOfRangeException)); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Max, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - e = TestHelper.ExpectedException( - () => blob.EndSetSequenceNumber(result), - "SetSequenceNumber with Max should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - result = blob.BeginSetSequenceNumber(SequenceNumberAction.Increment, 1, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - e = TestHelper.ExpectedException( - () => blob.EndSetSequenceNumber(result), - "SetSequenceNumber with Increment should require null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - using (MemoryStream stream = new MemoryStream(buffer)) - { - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndWritePages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndClearPages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndWritePages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndClearPages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndWritePages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - result = blob.BeginClearPages(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndClearPages(result), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginUploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginUploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - stream.Seek(0, SeekOrigin.Begin); - result = blob.BeginUploadFromStream(stream, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Use sequence number conditions on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSequenceNumberTask() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - blob.CreateAsync(buffer.Length).Wait(); - Assert.IsNull(blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumberAsync(SequenceNumberAction.Update, 5).Wait(); - Assert.AreEqual(5, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 7).Wait(); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 3).Wait(); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, null).Wait(); - Assert.AreEqual(8, blob.Properties.PageBlobSequenceNumber); - - StorageException e = TestHelper.ExpectedExceptionTask( - blob.SetSequenceNumberAsync(SequenceNumberAction.Update, null), - "SetSequenceNumber with Update should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = TestHelper.ExpectedExceptionTask( - blob.SetSequenceNumberAsync(SequenceNumberAction.Update, -1), - "Negative sequence numbers are not supported"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentOutOfRangeException)); - - e = TestHelper.ExpectedExceptionTask( - blob.SetSequenceNumberAsync(SequenceNumberAction.Max, null), - "SetSequenceNumber with Max should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = TestHelper.ExpectedExceptionTask( - blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, 1), - "SetSequenceNumber with Increment should require null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - using (MemoryStream stream = new MemoryStream(buffer)) - { - stream.Seek(0, SeekOrigin.Begin); - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null).Wait(); - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null).Wait(); - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null).Wait(); - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null).Wait(); - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedExceptionTask( - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedExceptionTask( - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedExceptionTask( - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedExceptionTask( - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - TestHelper.ExpectedExceptionTask( - blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null), - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - TestHelper.ExpectedExceptionTask( - blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null), - "Sequence number condition should cause Clear Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null).Wait(); - - stream.Seek(0, SeekOrigin.Begin); - blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null).Wait(); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Page blob creation should fail with invalid size")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCreateInvalidSize() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - TestHelper.ExpectedException( - () => blob.Create(-1), - "Creating a page blob with size<0 should fail", - HttpStatusCode.BadRequest); - TestHelper.ExpectedException( - () => blob.Create(1L * 1024 * 1024 * 1024 * 1024 + 1), - "Creating a page blob with size>1TB should fail", - HttpStatusCode.BadRequest); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDeleteIfExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - Assert.IsFalse(blob.DeleteIfExists()); - blob.Create(0); - Assert.IsTrue(blob.DeleteIfExists()); - Assert.IsFalse(blob.DeleteIfExists()); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDeleteIfExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - IAsyncResult result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob.EndDeleteIfExists(result)); - result = blob.BeginCreate(1024, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndCreate(result); - result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(blob.EndDeleteIfExists(result)); - result = blob.BeginDeleteIfExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob.EndDeleteIfExists(result)); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Try to delete a non-existing page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDeleteIfExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - Assert.IsFalse(blob.DeleteIfExistsAsync().Result); - blob.CreateAsync(0).Wait(); - Assert.IsTrue(blob.DeleteIfExistsAsync().Result); - Assert.IsFalse(blob.DeleteIfExistsAsync().Result); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobExists() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - Assert.IsFalse(blob2.Exists()); - - blob.Create(2048); - - Assert.IsTrue(blob2.Exists()); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.Delete(); - - Assert.IsFalse(blob2.Exists()); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobExistsAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - - try - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob2.EndExists(result)); - - blob.Create(2048); - - result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsTrue(blob2.EndExists(result)); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.Delete(); - - result = blob2.BeginExists( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Assert.IsFalse(blob2.EndExists(result)); - } - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobExistsTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - - try - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - Assert.IsFalse(blob2.ExistsAsync().Result); - - blob.CreateAsync(2048).Wait(); - - Assert.IsTrue(blob2.ExistsAsync().Result); - Assert.AreEqual(2048, blob2.Properties.Length); - - blob.DeleteAsync().Wait(); - - Assert.IsFalse(blob2.ExistsAsync().Result); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobFetchAttributes() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - Assert.AreEqual(1024, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob.Properties.BlobType); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobFetchAttributesAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - IAsyncResult result = blob.BeginCreate(1024, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndCreate(result); - Assert.AreEqual(1024, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob.Properties.BlobType); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob2.Properties.BlobType); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobFetchAttributesTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(1024).Wait(); - Assert.AreEqual(1024, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob.Properties.BlobType); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetProperties() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - blob.SetProperties(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudPageBlob blob3 = container.GetPageBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - blob3.DownloadToStream(stream, null, options); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - CloudPageBlob blob4 = (CloudPageBlob)container.ListBlobs().First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetPropertiesAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - IAsyncResult result = blob.BeginCreate(1024, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndCreate(result); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - result = blob.BeginSetProperties( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetProperties(result); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudPageBlob blob3 = container.GetPageBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - result = blob3.BeginDownloadToStream(stream, null, options, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob3.EndDownloadToStream(result); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - result = container.BeginListBlobsSegmented(null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - CloudPageBlob blob4 = (CloudPageBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetPropertiesTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(1024).Wait(); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - Thread.Sleep(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - blob.SetPropertiesAsync().Wait(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudPageBlob blob3 = container.GetPageBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - blob3.DownloadToStreamAsync(stream, null, options, null).Wait(); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - CloudPageBlob blob4 = (CloudPageBlob)container.ListBlobsSegmentedAsync(null).Result.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Try retrieving properties of a page blob using a block blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobFetchAttributesInvalidType() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - StorageException e = TestHelper.ExpectedException( - () => blob2.FetchAttributes(), - "Fetching attributes of a page blob using block blob reference should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that creating a page blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCreateWithMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - blob.Create(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that a page blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributes(); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - StorageException e = TestHelper.ExpectedException( - () => blob.SetMetadata(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - e = TestHelper.ExpectedException( - () => blob.SetMetadata(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - blob.SetMetadata(); - - blob2.FetchAttributes(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - CloudPageBlob blob3 = (CloudPageBlob)container.ListBlobs(null, true, BlobListingDetails.Metadata, null, null).First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - blob.SetMetadata(); - - blob2.FetchAttributes(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Verify that a page blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetMetadataAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - IAsyncResult result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - Exception e = TestHelper.ExpectedException( - () => blob.EndSetMetadata(result), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - e = TestHelper.ExpectedException( - () => blob.EndSetMetadata(result), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetMetadata(result); - - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - result = container.BeginListBlobsSegmented(null, true, BlobListingDetails.Metadata, null, null, null, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - BlobResultSegment results = container.EndListBlobsSegmented(result); - CloudPageBlob blob3 = (CloudPageBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - result = blob.BeginSetMetadata( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndSetMetadata(result); - - result = blob2.BeginFetchAttributes( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob2.EndFetchAttributes(result); - Assert.AreEqual(0, blob2.Metadata.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Verify that a page blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSetMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(1024).Wait(); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, blob2.Metadata.Count); - - blob.Metadata["key1"] = null; - StorageException e = TestHelper.ExpectedExceptionTask( - blob.SetMetadataAsync(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - e = TestHelper.ExpectedExceptionTask( - blob.SetMetadataAsync(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - blob.SetMetadataAsync().Wait(); - - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - CloudPageBlob blob3 = - (CloudPageBlob) - container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null) - .Result - .Results - .First(); - - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - blob.SetMetadataAsync().Wait(); - - blob2.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload/clear pages in a page blob and then verify page ranges")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobGetPageRanges() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(4 * 1024); - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePages(memoryStream, 512); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePages(memoryStream, 3 * 1024); - } - - blob.ClearPages(1024, 1024); - blob.ClearPages(0, 512); - - IEnumerable pageRanges = blob.GetPageRanges(); - List expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 4 * 1024 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - pageRanges = blob.GetPageRanges(1024, 1024); - Assert.AreEqual(0, pageRanges.Count()); - - pageRanges = blob.GetPageRanges(512, 3 * 1024); - expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 7 * 512 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - Exception e = TestHelper.ExpectedException( - () => blob.GetPageRanges(1024), - "Get Page Ranges with an offset but no count should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload/clear pages in a page blob and then verify page ranges")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobGetPageRangesAPM() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(4 * 1024); - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePages(memoryStream, 512); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePages(memoryStream, 3 * 1024); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginClearPages(1024, 1024, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - result = blob.BeginClearPages(0, 512, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndClearPages(result); - - result = blob.BeginGetPageRanges( - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - IEnumerable pageRanges = blob.EndGetPageRanges(result); - List expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 4 * 1024 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - result = blob.BeginGetPageRanges(1024, - 1024, - null, - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageRanges = blob.EndGetPageRanges(result); - expectedPageRanges = new List(); - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - result = blob.BeginGetPageRanges(512, - 3 * 1024, - null, - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageRanges = blob.EndGetPageRanges(result); - expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 7 * 512 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - result = blob.BeginGetPageRanges(1024, - null, - null, - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - StorageException e = TestHelper.ExpectedException( - () => blob.EndGetPageRanges(result), - "Get Page Ranges with an offset but no count should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Upload/clear pages in a page blob and then verify page ranges")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobGetPageRangesTask() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(4 * 1024).Wait(); - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePagesAsync(memoryStream, 512, null).Wait(); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - blob.WritePagesAsync(memoryStream, 3 * 1024, null).Wait(); - } - - blob.ClearPagesAsync(1024, 1024).Wait(); - blob.ClearPagesAsync(0, 512).Wait(); - - IEnumerable pageRanges = blob.GetPageRangesAsync().Result; - List expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 4 * 1024 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - pageRanges = blob.GetPageRangesAsync(1024, 1024, null, null, null).Result; - Assert.AreEqual(0, pageRanges.Count()); - - pageRanges = blob.GetPageRangesAsync(512, 3 * 1024, null, null, null).Result; - expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 7 * 512 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - Exception e = TestHelper.ExpectedExceptionTask( - blob.GetPageRangesAsync(1024, null, null, null, null), - "Get Page Ranges with an offset but no count should fail"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Upload pages to a page blob and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobWritePages() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(4 * 1024 * 1024); - - using (MemoryStream memoryStream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.WritePages(memoryStream, 0), - "Zero-length WritePages should fail"); - - memoryStream.SetLength(4 * 1024 * 1024 + 1); - TestHelper.ExpectedException( - () => blob.WritePages(memoryStream, 0), - ">4MB WritePages should fail"); - } - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - TestHelper.ExpectedException( - () => blob.WritePages(memoryStream, 512), - "Writing out-of-range pages should fail", - HttpStatusCode.RequestedRangeNotSatisfiable, - "InvalidPageRange"); - - memoryStream.Seek(0, SeekOrigin.Begin); - blob.WritePages(memoryStream, 0, contentMD5); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - TestHelper.ExpectedException( - () => blob.WritePages(memoryStream, 0, contentMD5), - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - blob.WritePages(memoryStream, 0); - resultingData.Seek(0, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - - offset = buffer.Length - 2048; - memoryStream.Seek(offset, SeekOrigin.Begin); - blob.WritePages(memoryStream, 1024); - resultingData.Seek(1024, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - using (MemoryStream blobData = new MemoryStream()) - { - blob.DownloadToStream(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToStreamAPM() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream(originalBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext context = new OperationContext(); - result = blob.BeginDownloadRangeToStream(downloadedBlob, - 0, /* offset */ - buffer.Length, /* Length */ - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadRangeToStream(result); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload pages to a page blob and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobWritePagesAPM() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(4 * 1024 * 1024); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - using (MemoryStream memoryStream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.BeginWritePages(memoryStream, 0, null, null, null), - "Zero-length WritePages should fail"); - - memoryStream.SetLength(4 * 1024 * 1024 + 1); - TestHelper.ExpectedException( - () => blob.BeginWritePages(memoryStream, 0, null, null, null), - ">4MB WritePages should fail"); - } - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - result = blob.BeginWritePages(memoryStream, 512, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndWritePages(result), - "Writing out-of-range pages should fail", - HttpStatusCode.RequestedRangeNotSatisfiable, - "InvalidPageRange"); - - memoryStream.Seek(0, SeekOrigin.Begin); - result = blob.BeginWritePages(memoryStream, 0, contentMD5, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - result = blob.BeginWritePages(memoryStream, 0, contentMD5, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndWritePages(result), - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - result = blob.BeginWritePages(memoryStream, 0, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - resultingData.Seek(0, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - - offset = buffer.Length - 2048; - memoryStream.Seek(offset, SeekOrigin.Begin); - result = blob.BeginWritePages(memoryStream, 1024, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndWritePages(result); - resultingData.Seek(1024, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - using (MemoryStream blobData = new MemoryStream()) - { - blob.DownloadToStream(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobDownloadToStreamTask() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(originalBlob).Wait(); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext context = new OperationContext(); - blob.DownloadRangeToStreamAsync(downloadedBlob, 0, buffer.Length).Wait(); - TestHelper.AssertStreamsAreEqual(originalBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload pages to a page blob and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobWritePagesTask() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(4 * 1024 * 1024).Wait(); - - using (MemoryStream memoryStream = new MemoryStream()) - { - TestHelper.ExpectedException( - () => blob.WritePagesAsync(memoryStream, 0, null), - "Zero-length WritePages should fail"); - - memoryStream.SetLength(4 * 1024 * 1024 + 1); - TestHelper.ExpectedException( - () => blob.WritePagesAsync(memoryStream, 0, null), - ">4MB WritePages should fail"); - } - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - TestHelper.ExpectedExceptionTask( - blob.WritePagesAsync(memoryStream, 512, null), - "Writing out-of-range pages should fail", - HttpStatusCode.RequestedRangeNotSatisfiable, - "InvalidPageRange"); - - memoryStream.Seek(0, SeekOrigin.Begin); - blob.WritePagesAsync(memoryStream, 0, contentMD5).Wait(); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - TestHelper.ExpectedExceptionTask( - blob.WritePagesAsync(memoryStream, 0, contentMD5), - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - blob.WritePagesAsync(memoryStream, 0, null).Wait(); - resultingData.Seek(0, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - - offset = buffer.Length - 2048; - memoryStream.Seek(offset, SeekOrigin.Begin); - blob.WritePagesAsync(memoryStream, 1024, null).Wait(); - resultingData.Seek(1024, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - using (MemoryStream blobData = new MemoryStream()) - { - blob.DownloadToStreamAsync(blobData).Wait(); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, false, true); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, false, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, false, true); - - blob = container.GetPageBlobReference("blob3"); - blob.Create(1024); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, false, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamAPMWithAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, true, true); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, true, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, true, true); - - blob = container.GetPageBlobReference("blob3"); - blob.Create(1024); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, true, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, accessCondition, 0, true, true); - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamWithAccessConditionTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, accessCondition, 0, true); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(1024).Wait(); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, accessCondition, 0, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, accessCondition, 0, true); - - blob = container.GetPageBlobReference("blob3"); - blob.CreateAsync(1024).Wait(); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, accessCondition, 0, true), - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, accessCondition, 0, true); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStream() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, null, 0, false, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, null, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, null, 0, true, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, null, null, 1024, true, true); - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - try - { - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, null, 0, true); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, null, null, 1024, true); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLength() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - // Upload half of the stream - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 0, false, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 1024, false, true); - - // Upload full stream - this.CloudPageBlobUploadFromStream(container, 6 * 512, 6 * 512, null, 0, false, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 4 * 512, null, 1024, false, true); - - // Exclude last page - this.CloudPageBlobUploadFromStream(container, 6 * 512, 5 * 512, null, 0, false, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 1024, false, true); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLengthAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - // Upload half of the stream - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 0, true, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 1024, true, true); - - // Upload full stream - this.CloudPageBlobUploadFromStream(container, 6 * 512, 6 * 512, null, 0, true, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 4 * 512, null, 1024, true, true); - - // Exclude last page - this.CloudPageBlobUploadFromStream(container, 6 * 512, 5 * 512, null, 0, true, true); - this.CloudPageBlobUploadFromStream(container, 6 * 512, 3 * 512, null, 1024, true, true); - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLengthTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - try - { - // Upload half of the stream - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 3 * 512, null, 0, true); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 3 * 512, null, 1024, true); - - // Upload full stream - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 6 * 512, null, 0, true); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 4 * 512, null, 1024, true); - - // Exclude last page - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 5 * 512, null, 0, true); - this.CloudPageBlobUploadFromStreamTask(container, 6 * 512, 3 * 512, null, 1024, true); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLengthInvalid() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 3 * 512, 3 * 512 + 1, null, 0, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 3 * 512, 3 * 512 + 1025, null, 1024, false, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLengthInvalidAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.Create(); - try - { - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 3 * 512, 3 * 512 + 1, null, 0, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStream(container, 3 * 512, 3 * 512 + 1025, null, 1024, true, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadFromStreamLengthInvalidTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.CreateAsync().Wait(); - try - { - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStreamTask(container, 3 * 512, 3 * 512 + 1, null, 0, false), - "The given stream does not contain the requested number of bytes from its given position."); - - TestHelper.ExpectedException( - () => this.CloudPageBlobUploadFromStreamTask(container, 3 * 512, 3 * 512 + 1025, null, 1024, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.DeleteAsync().Wait(); - } - } -#endif - - private void CloudPageBlobUploadFromStream(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, int startOffset, bool isAsync, bool testMd5) - { - byte[] buffer = GetRandomBuffer(size); - - MD5 hasher = MD5.Create(); - string md5 = string.Empty; - if (testMd5) - { - md5 = Convert.ToBase64String(hasher.ComputeHash(buffer, startOffset, copyLength.HasValue ? (int)copyLength : buffer.Length - startOffset)); - } - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 512; - - using (MemoryStream originalBlob = new MemoryStream()) - { - originalBlob.Write(buffer, startOffset, buffer.Length - startOffset); - - using (MemoryStream sourceStream = new MemoryStream(buffer)) - { - sourceStream.Seek(startOffset, SeekOrigin.Begin); - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - if (isAsync) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - if (copyLength.HasValue) - { - ICancellableAsyncResult result = blob.BeginUploadFromStream( - sourceStream, copyLength.Value, accessCondition, options, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - else - { - ICancellableAsyncResult result = blob.BeginUploadFromStream( - sourceStream, accessCondition, options, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - } - } - else - { - if (copyLength.HasValue) - { - blob.UploadFromStream(sourceStream, copyLength.Value, accessCondition, options); - } - else - { - blob.UploadFromStream(sourceStream, accessCondition, options); - } - } - } - - blob.FetchAttributes(); - if (testMd5) - { - Assert.AreEqual(md5, blob.Properties.ContentMD5); - } - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - if (isAsync) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - ICancellableAsyncResult result = blob.BeginDownloadToStream(downloadedBlob, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - } - } - else - { - blob.DownloadToStream(downloadedBlob); - } - - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlob, - downloadedBlob, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlob.Length); - } - } - } - -#if TASK - private void CloudPageBlobUploadFromStreamTask(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, int startOffset, bool testMd5) - { - try - { - byte[] buffer = GetRandomBuffer(size); - - MD5 hasher = MD5.Create(); - string md5 = string.Empty; - if (testMd5) - { - md5 = Convert.ToBase64String(hasher.ComputeHash(buffer, startOffset, copyLength.HasValue ? (int)copyLength : buffer.Length - startOffset)); - } - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 512; - - using (MemoryStream originalBlob = new MemoryStream()) - { - originalBlob.Write(buffer, startOffset, buffer.Length - startOffset); - - using (MemoryStream sourceStream = new MemoryStream(buffer)) - { - sourceStream.Seek(startOffset, SeekOrigin.Begin); - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - if (copyLength.HasValue) - { - blob.UploadFromStreamAsync(sourceStream, copyLength.Value, accessCondition, options, null).Wait(); - } - else - { - blob.UploadFromStreamAsync(sourceStream, accessCondition, options, null).Wait(); - } - } - - blob.FetchAttributesAsync().Wait(); - if (testMd5) - { - Assert.AreEqual(md5, blob.Properties.ContentMD5); - } - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - blob.DownloadToStreamAsync(downloadedBlob).Wait(); - - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlob, - downloadedBlob, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlob.Length); - } - } - } - catch (AggregateException ex) - { - throw ex.InnerException; - } - } -#endif - - [TestMethod] - [Description("Create snapshots of a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshot() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.UploadFromStream(originalData); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudPageBlob snapshot1 = blob.CreateSnapshot(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudPageBlob snapshot2 = blob.CreateSnapshot(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributes(); - snapshot2.FetchAttributes(); - blob.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudPageBlob snapshot1Clone = new CloudPageBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - snapshot1Clone.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudPageBlob snapshotCopy = container.GetPageBlobReference("blob2"); - snapshotCopy.StartCopyFromBlob(TestHelper.Defiddler(snapshot1.Uri)); - WaitForCopy(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.OpenWrite(1024), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = snapshot1.OpenRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - blob.Create(1024); - - using (Stream snapshotStream = snapshot1.OpenRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create snapshots of a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshotAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginUploadFromStream(originalData, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - result = blob.BeginCreateSnapshot(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudPageBlob snapshot1 = blob.EndCreateSnapshot(result); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - result = blob.BeginCreateSnapshot(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudPageBlob snapshot2 = blob.EndCreateSnapshot(result); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributes(); - snapshot2.FetchAttributes(); - blob.FetchAttributes(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudPageBlob snapshotCopy = container.GetPageBlobReference("blob2"); - result = snapshotCopy.BeginStartCopyFromBlob(snapshot1, null, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - snapshotCopy.EndStartCopyFromBlob(result); - WaitForCopy(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.BeginOpenWrite(1024, ar => waitHandle.Set(), null), - "Trying to write to a blob snapshot should fail"); - - result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - using (Stream snapshotStream = snapshot1.EndOpenRead(result)) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - result = blob.BeginCreate(1024, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndCreate(result); - - result = snapshot1.BeginOpenRead(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - using (Stream snapshotStream = snapshot1.EndOpenRead(result)) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = container.ListBlobs(null, true, BlobListingDetails.All, null, null).ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create snapshots of a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshotTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.UploadFromStreamAsync(originalData).Wait(); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudPageBlob snapshot1 = blob.CreateSnapshotAsync().Result; - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudPageBlob snapshot2 = blob.CreateSnapshotAsync().Result; - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - snapshot1.FetchAttributesAsync().Wait(); - snapshot2.FetchAttributesAsync().Wait(); - blob.FetchAttributesAsync().Wait(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudPageBlob snapshot1Clone = new CloudPageBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - snapshot1Clone.FetchAttributesAsync().Wait(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudPageBlob snapshotCopy = container.GetPageBlobReference("blob2"); - snapshotCopy.StartCopyFromBlobAsync(snapshot1, null, null, null, null).Wait(); - WaitForCopy(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - TestHelper.ExpectedException( - () => snapshot1.OpenWriteAsync(1024), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - blob.CreateAsync(1024).Wait(); - - using (Stream snapshotStream = snapshot1.OpenReadAsync().Result) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - List blobs = - container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null) - .Result - .Results - .ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshotMetadata() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadata(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudPageBlob snapshot = blob.CreateSnapshot(snapshotMetadata); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributes(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshotMetadataAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadata(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - IAsyncResult result; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginCreateSnapshot(snapshotMetadata, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudPageBlob snapshot = blob.EndCreateSnapshot(result); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributes(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSnapshotMetadataTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.CreateAsync(1024, null, null, new OperationContext()).Wait(); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - blob.SetMetadataAsync().Wait(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudPageBlob snapshot = blob.CreateSnapshotAsync(snapshotMetadata, null, null, null).Result; - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - snapshot.FetchAttributesAsync().Wait(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobConditionalAccess() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(1024); - blob.FetchAttributes(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - blob.SetMetadata(AccessCondition.GenerateIfMatchCondition(currentETag), null); - - blob.FetchAttributes(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNoneMatchCondition(newETag), null), - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfMatchCondition(invalidETag), null), - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - blob.SetMetadata(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null); - - blob.FetchAttributes(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null), - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - blob.SetMetadata(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - TestHelper.ExpectedException( - () => blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null), - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - blob.SetMetadata(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null); - - blob.FetchAttributes(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test page blob methods on a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobMethodsOnBlockBlob() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - List blobs = CreateBlobs(container, 1, BlobType.BlockBlob); - CloudPageBlob blob = container.GetPageBlobReference(blobs.First()); - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0), - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - TestHelper.ExpectedException( - () => blob.ClearPages(0, 512), - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - TestHelper.ExpectedException( - () => blob.GetPageRanges(), - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test 512-byte page alignment")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobAlignment() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - TestHelper.ExpectedException( - () => blob.Create(511), - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => blob.Create(513), - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - blob.Create(512); - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(511); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(513); - TestHelper.ExpectedException( - () => blob.WritePages(stream, 0), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - blob.WritePages(stream, 0); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobUploadDownloadNoData() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob blob = container.GetPageBlobReference("blob"); - TestHelper.ExpectedException( - () => blob.UploadFromStream(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - blob.UploadFromStream(stream); - } - - TestHelper.ExpectedException( - () => blob.DownloadToStream(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - blob.DownloadToStream(stream); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Try operations with an invalid Sas and snapshot")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobInvalidSasAndSnapshot() - { - // Sas token creds. - string token = "?sp=abcde&sig=1"; - StorageCredentials creds = new StorageCredentials(token); - Assert.IsTrue(creds.IsSAS); - - // Client with shared key access. - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(GetRandomContainerName()); - try - { - container.Create(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, - }; - string sasToken = container.GetSharedAccessSignature(policy); - - string blobUri = container.Uri.AbsoluteUri + "/blob1" + sasToken; - TestHelper.ExpectedException( - () => new CloudPageBlob(new Uri(blobUri), container.ServiceClient.Credentials), - "Try to use SAS creds in Uri on a shared key client"); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Create(0); - CloudPageBlob snapshot = blob.CreateSnapshot(); - DateTimeOffset? wrongTime = snapshot.SnapshotTime.Value + TimeSpan.FromSeconds(10); - - string snapshotUri = snapshot.Uri + "?snapshot=" + wrongTime.Value.ToString(); - TestHelper.ExpectedException( - () => new CloudPageBlob(new Uri(snapshotUri), snapshot.SnapshotTime, container.ServiceClient.Credentials), - "Snapshot in Uri does not match snapshot on blob"); - - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Use IASyncResult's WaitHandle")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void IAsyncWaitHandleTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - IAsyncResult result; - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - result = blob.BeginCreate(0, null, null); - result.AsyncWaitHandle.WaitOne(); - blob.EndCreate(result); - - result = blob.BeginExists(null, null); - result.AsyncWaitHandle.WaitOne(); - Assert.IsTrue(blob.EndExists(result)); - - result = blob.BeginDelete(null, null); - result.AsyncWaitHandle.WaitOne(); - blob.EndDelete(result); - } - finally - { - container.DeleteIfExists(); - } - } - } -} - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CopyBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CopyBlobTest.cs deleted file mode 100644 index ef79f75b5517b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/CopyBlobTest.cs +++ /dev/null @@ -1,821 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Net; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CopyBlobTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("CopyFromBlob with Unicode source blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CopyBlobUsingUnicodeBlobName() - { - string _unicodeBlobName = "繁体字14a6c"; - string _nonUnicodeBlobName = "sample_file"; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - CloudBlockBlob blobUnicodeSource = container.GetBlockBlobReference(_unicodeBlobName); - string data = "Test content"; - UploadText(blobUnicodeSource, data, Encoding.UTF8); - CloudBlockBlob blobAsciiSource = container.GetBlockBlobReference(_nonUnicodeBlobName); - UploadText(blobAsciiSource, data, Encoding.UTF8); - - //Copy blobs over - CloudBlockBlob blobAsciiDest = container.GetBlockBlobReference(_nonUnicodeBlobName + "_copy"); - string copyId = blobAsciiDest.StartCopyFromBlob(TestHelper.Defiddler(blobAsciiSource)); - WaitForCopy(blobAsciiDest); - - CloudBlockBlob blobUnicodeDest = container.GetBlockBlobReference(_unicodeBlobName + "_copy"); - copyId = blobUnicodeDest.StartCopyFromBlob(TestHelper.Defiddler(blobUnicodeSource)); - WaitForCopy(blobUnicodeDest); - - Assert.AreEqual(CopyStatus.Success, blobUnicodeDest.CopyState.Status); - Assert.AreEqual(blobUnicodeSource.Uri.AbsolutePath, blobUnicodeDest.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.TotalBytes); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.BytesCopied); - Assert.AreEqual(copyId, blobUnicodeDest.CopyState.CopyId); - Assert.IsTrue(blobUnicodeDest.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - string copyId = copy.StartCopyFromBlob(TestHelper.Defiddler(source)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - TestHelper.ExpectedException( - () => copy.AbortCopy(copyId), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - source.FetchAttributes(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyTestAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = copy.BeginStartCopyFromBlob(TestHelper.Defiddler(source), - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - string copyId = copy.EndStartCopyFromBlob(result); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - result = copy.BeginAbortCopy(copyId, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => copy.EndAbortCopy(result), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - } - - source.FetchAttributes(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyTestTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - UploadTextTask(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadataAsync().Wait(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - string copyId = copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)).Result; - WaitForCopyTask(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - TestHelper.ExpectedExceptionTask( - copy.AbortCopyAsync(copyId), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - source.FetchAttributesAsync().Wait(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadTextTask(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributesAsync().Wait(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.DeleteAsync().Wait(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyTestWithMetadataOverride() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = copy.StartCopyFromBlob(TestHelper.Defiddler(source)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - source.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyFromSnapshotTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - string data = "String data"; - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudBlockBlob snapshot = source.CreateSnapshot(); - - //Modify source - string newData = "Hello"; - source.Metadata["Test"] = "newvalue"; - source.SetMetadata(); - source.Properties.ContentMD5 = null; - UploadText(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, DownloadText(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, DownloadText(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - source.FetchAttributes(); - snapshot.FetchAttributes(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - copy.StartCopyFromBlob(TestHelper.Defiddler(snapshot)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, DownloadText(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - string copyId = copy.StartCopyFromBlob(TestHelper.Defiddler(source)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - TestHelper.ExpectedException( - () => copy.AbortCopy(copyId), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - source.FetchAttributes(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyTestAPM() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = copy.BeginStartCopyFromBlob(TestHelper.Defiddler(source), - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - string copyId = copy.EndStartCopyFromBlob(result); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - result = copy.BeginAbortCopy(copyId, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => copy.EndAbortCopy(result), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - } - - source.FetchAttributes(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyTestTask() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.CreateAsync().Wait(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - UploadTextTask(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadataAsync().Wait(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - string copyId = copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)).Result; - WaitForCopyTask(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - TestHelper.ExpectedExceptionTask( - copy.AbortCopyAsync(copyId), - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - source.FetchAttributesAsync().Wait(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadTextTask(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributesAsync().Wait(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.DeleteAsync().Wait(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyTestWithMetadataOverride() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = copy.StartCopyFromBlob(TestHelper.Defiddler(source)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = DownloadText(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - source.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyFromSnapshotTest() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - source.SetMetadata(); - - CloudPageBlob snapshot = source.CreateSnapshot(); - - //Modify source - string newData = new string('b', 512); - source.Metadata["Test"] = "newvalue"; - source.SetMetadata(); - source.Properties.ContentMD5 = null; - UploadText(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, DownloadText(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, DownloadText(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - source.FetchAttributes(); - snapshot.FetchAttributes(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - copy.StartCopyFromBlob(TestHelper.Defiddler(snapshot)); - WaitForCopy(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, DownloadText(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - copy.FetchAttributes(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - copy.Delete(); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob with source access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobCopyWithSourceAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - string validLeaseId = Guid.NewGuid().ToString(); - string leaseId = source.AcquireLease(TimeSpan.FromSeconds(60), validLeaseId); - string invalidLeaseId = Guid.NewGuid().ToString(); - - source.FetchAttributes(); - AccessCondition sourceAccessCondition1 = AccessCondition.GenerateIfNotModifiedSinceCondition(source.Properties.LastModified.Value); - CloudBlockBlob copy1 = container.GetBlockBlobReference("copy1"); - copy1.StartCopyFromBlob(TestHelper.Defiddler(source), sourceAccessCondition1); - WaitForCopy(copy1); - Assert.AreEqual(CopyStatus.Success, copy1.CopyState.Status); - - AccessCondition sourceAccessCondition2 = AccessCondition.GenerateLeaseCondition(invalidLeaseId); - CloudBlockBlob copy2 = container.GetBlockBlobReference("copy2"); - TestHelper.ExpectedException(() => copy2.StartCopyFromBlob(TestHelper.Defiddler(source), sourceAccessCondition2), "A lease condition cannot be specified on the source of a copy."); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy a blob with source access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobCopyWithSourceAccessCondition() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - string data = new string('a', 512); - UploadText(source, data, Encoding.UTF8); - string validLeaseId = Guid.NewGuid().ToString(); - string leaseId = source.AcquireLease(TimeSpan.FromSeconds(60), validLeaseId); - string invalidLeaseId = Guid.NewGuid().ToString(); - - source.FetchAttributes(); - AccessCondition sourceAccessCondition1 = AccessCondition.GenerateIfNotModifiedSinceCondition(source.Properties.LastModified.Value); - CloudPageBlob copy1 = container.GetPageBlobReference("copy1"); - copy1.StartCopyFromBlob(TestHelper.Defiddler(source), sourceAccessCondition1); - WaitForCopy(copy1); - Assert.AreEqual(CopyStatus.Success, copy1.CopyState.Status); - - AccessCondition sourceAccessCondition2 = AccessCondition.GenerateLeaseCondition(invalidLeaseId); - CloudPageBlob copy2 = container.GetPageBlobReference("copy2"); - TestHelper.ExpectedException(() => copy2.StartCopyFromBlob(TestHelper.Defiddler(source), sourceAccessCondition2), "A lease condition cannot be specified on the source of a copy."); - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/EscapingTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/EscapingTests.cs deleted file mode 100644 index 9fc9528844017..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/EscapingTests.cs +++ /dev/null @@ -1,172 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Linq; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class EscapingTests : BlobTestBase - { - internal const string UnreservedCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-._~"; - internal const string GenDelimeters = "?:#[]@"; - internal const string SubDelimeters = "!$'()*+,;="; - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("The test case for unsafe chars")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithSpace() - { - PrefixEscapingTest("prefix test", "blob test"); - } - - [TestMethod] - [Description("The test case for escape chars")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithPercent20() - { - PrefixEscapingTest("prefix%20test", "blob%20test"); - } - - [TestMethod] - [Description("The test case for unreserved chars")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithUnreservedCharacters() - { - PrefixEscapingTest(UnreservedCharacters, UnreservedCharacters); - } - - [TestMethod] - [Description("The test case for reserved chars(Gen-Delimeters)")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithGenDelimeter() - { - string genDelimeters = GenDelimeters; - - // Remove the char ":" in the given string for .Net 4.0 because In .Net 4.0 - // Uri.MakeRelativeUri(...) automatically add "./" when the input has ‘:’ before the first ‘/’. - // It's an undocumented change from .Net 3.5 to .Net 4.0. - if (Environment.Version.ToString().StartsWith("4.")) - { - genDelimeters = genDelimeters.Replace(":", null); - } - - PrefixEscapingTest(genDelimeters, genDelimeters); - } - - [TestMethod] - [Description("The test case for reserved chars(Sub-Delimeters)")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithSubDelimeter() - { - PrefixEscapingTest(SubDelimeters, SubDelimeters); - } - - [TestMethod] - [Description("The test case for unicode chars")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PrefixTestWithUnicode() - { - PrefixEscapingTest("prefix中文test", "char中文test"); - } - - private void PrefixEscapingTest(string prefix, string blobName) - { - CloudBlobClient service = GenerateCloudBlobClient(); - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - container.Create(); - string text = Guid.NewGuid().ToString(); - - // Create from CloudBlobContainer. - CloudBlockBlob originalBlob = container.GetBlockBlobReference(prefix + "/" + blobName); - originalBlob.PutBlockList(new string[] { }); - - // List blobs from container. - IListBlobItem blobFromContainerListingBlobs = container.ListBlobs(null, true).First(); - Assert.AreEqual(originalBlob.Uri, blobFromContainerListingBlobs.Uri); - - CloudBlockBlob uriBlob = new CloudBlockBlob(originalBlob.Uri, service.Credentials); - - // Check Name - Assert.AreEqual(prefix + "/" + blobName, originalBlob.Name); - Assert.AreEqual(prefix + "/" + blobName, uriBlob.Name); - - // Absolute URI access from CloudBlockBlob - CloudBlockBlob blobInfo = new CloudBlockBlob(originalBlob.Uri, service.Credentials); - blobInfo.FetchAttributes(); - - // Access from CloudBlobDirectory - CloudBlobDirectory cloudBlobDirectory = container.GetDirectoryReference(prefix); - CloudBlockBlob blobFromCloudBlobDirectory = cloudBlobDirectory.GetBlockBlobReference(blobName); - Assert.AreEqual(blobInfo.Uri, blobFromCloudBlobDirectory.Uri); - - // Copy blob verification. - CloudBlockBlob copyBlob = container.GetBlockBlobReference(prefix + "/" + blobName + "copy"); - copyBlob.StartCopyFromBlob(blobInfo.Uri); - copyBlob.FetchAttributes(); - } - finally - { - container.Delete(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/LeaseTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/LeaseTests.cs deleted file mode 100644 index f07bfd855063d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/LeaseTests.cs +++ /dev/null @@ -1,7736 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Blob.Protocol; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class LeaseTests : BlobTestBase - { - /// - /// The prefix to use for the current test. New containers and blobs in the root container begin with this prefix - /// to avoid conflicting with other tests or concurrent runs of the same test. This also allows a test to easily - /// clean itself up and to have a persistent recoverable state if a test fails. - /// - private string prefix; - - /// - /// The client for the blob service. - /// - private CloudBlobClient blobClient; - - /// - /// Create the given blob and, if necessary, its container. - /// - /// The blob to create. - internal static void CreateBlob(ICloudBlob blob) - { - blob.Container.CreateIfNotExists(); - UploadText(blob, "LeaseTestBlobContent", Encoding.UTF8); - } - -#if TASK - /// - /// Create the given blob and, if necessary, its container. - /// - /// The blob to create. - internal static void CreateBlobTask(ICloudBlob blob) - { - blob.Container.CreateIfNotExistsAsync().Wait(); - UploadTextTask(blob, "LeaseTestBlobContent", Encoding.UTF8); - } -#endif - - /// - /// Get a reference to a container of the given name, prepending the current prefix. - /// - /// The name of the container to which the prefix will be prepended. - /// A reference to the container. - internal CloudBlobContainer GetContainerReference(string rootName) - { - return this.blobClient.GetContainerReference(string.Format("{0}-{1}", this.prefix, rootName)); - } - - [TestInitialize] - public void TestInitialize() - { - this.blobClient = GenerateCloudBlobClient(); - - // Create and log a new prefix for this test. - this.prefix = Guid.NewGuid().ToString("N"); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - // Retire this test's prefix. No other cleanup is done here. - this.prefix = null; - - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - /// - /// Deletes all containers beginning with the current prefix, and all blobs in the root container beginning with the current prefix. - /// Any existing lease is broken before the resource is deleted. All exceptions are ignored. - /// - internal void DeleteAll() - { - try - { - // Delete all containers with prefix - foreach (CloudBlobContainer container in this.blobClient.ListContainers(this.prefix, ContainerListingDetails.None)) - { - try - { - container.BreakLease(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - container.Delete(); - } - catch (Exception) - { - } - } - - // Delete all blobs in root container with prefix - CloudBlobContainer rc = this.blobClient.GetRootContainerReference(); - foreach (ICloudBlob blob in rc.ListBlobs(this.prefix, true, BlobListingDetails.None, null, null)) - { - try - { - blob.BreakLease(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - blob.Delete(DeleteSnapshotsOption.IncludeSnapshots, null /* access conditions */, null /* options */); - } - catch (Exception) - { - } - } - } - catch (Exception) - { - } - } - -#if TASK - /// - /// Deletes all containers beginning with the current prefix, and all blobs in the root container beginning with the current prefix. - /// Any existing lease is broken before the resource is deleted. All exceptions are ignored. - /// - internal void DeleteAllTask() - { - try - { - // Delete all containers with prefix - foreach (CloudBlobContainer container in this.blobClient.ListContainers(this.prefix, ContainerListingDetails.None)) - { - try - { - container.BreakLeaseAsync(TimeSpan.Zero).Wait(); - } - catch (Exception) - { - } - - try - { - container.DeleteAsync().Wait(); - } - catch (Exception) - { - } - } - - // Delete all blobs in root container with prefix - CloudBlobContainer rc = this.blobClient.GetRootContainerReference(); - foreach (ICloudBlob blob in rc.ListBlobs(this.prefix, true, BlobListingDetails.None, null, null)) - { - try - { - blob.BreakLeaseAsync(TimeSpan.Zero).Wait(); - } - catch (Exception) - { - } - - try - { - blob.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots, null /* access conditions */, null /* options */, new OperationContext()); - } - catch (Exception) - { - } - } - } - catch (Exception) - { - } - } -#endif - - /// - /// Puts the lease on the given blob in an available state. - /// - /// The blob with the lease. - internal static void SetAvailableState(ICloudBlob blob) - { - bool shouldBreakFirst = false; - - try - { - blob.DeleteIfExists(); - } - catch (StorageException exception) - { - if (exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - shouldBreakFirst = true; - } - else - { - throw; - } - } - - if (shouldBreakFirst) - { - blob.BreakLease(TimeSpan.Zero); - blob.Delete(); - } - CreateBlob(blob); - } - - /// - /// Puts the lease on the given blob in an available state. - /// - /// The blob with the lease. - internal static void SetAvailableStateAPM(ICloudBlob blob) - { - bool shouldBreakFirst = false; - - try - { - blob.DeleteIfExists(); - } - catch (StorageException exception) - { - if (exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - shouldBreakFirst = true; - } - else - { - throw; - } - } - - if (shouldBreakFirst) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndBreakLease(result); - blob.Delete(); - } - } - CreateBlob(blob); - } - -#if TASK - /// - /// Puts the lease on the given blob in an available state. - /// - /// The blob with the lease. - internal static void SetAvailableStateTask(ICloudBlob blob) - { - bool shouldBreakFirst = false; - - try - { - blob.DeleteIfExistsAsync().Wait(); - } - catch (AggregateException ex) - { - StorageException exception = ex.InnerException as StorageException; - if (exception == null) - { - throw; - } - - if (exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - shouldBreakFirst = true; - } - else - { - throw; - } - } - - if (shouldBreakFirst) - { - blob.BreakLeaseAsync(TimeSpan.Zero).Wait(); - - blob.DeleteAsync().Wait(); - } - CreateBlobTask(blob); - } -#endif - - /// - /// Puts the lease on the given blob in a leased state. - /// - /// The blob with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static string SetLeasedState(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - SetAvailableState(blob); - return blob.AcquireLease(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given blob in a leased state. - /// - /// The blob with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static string SetLeasedStateAPM(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - SetAvailableStateAPM(blob); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginAcquireLease(leaseTime, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - } - return blob.EndAcquireLease(result); - } - -#if TASK - /// - /// Puts the lease on the given blob in a leased state. - /// - /// The blob with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static string SetLeasedStateTask(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - SetAvailableStateTask(blob); - return blob.AcquireLeaseAsync(leaseTime, leaseId).Result; - } -#endif - - /// - /// Puts the lease on the given blob in a renewed state. - /// - /// The blob with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static string SetRenewedState(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = SetLeasedState(blob, leaseTime); - blob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a released state. - /// - /// The blob with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static string SetReleasedState(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = SetLeasedState(blob, leaseTime); - blob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a released state. - /// - /// The blob with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static string SetReleasedStateAPM(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = SetLeasedStateAPM(blob, leaseTime); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = blob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndReleaseLease(result); - return leaseId; - } - } - -#if TASK - /// - /// Puts the lease on the given blob in a released state. - /// - /// The blob with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static string SetReleasedStateTask(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = SetLeasedStateAPM(blob, leaseTime); - blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - return leaseId; - } -#endif - - /// - /// Puts the lease on the given blob in a breaking state for 60 seconds. - /// - /// The blob with the lease. - /// The lease ID of the current (but breaking) lease. - internal static string SetBreakingState(ICloudBlob blob) - { - string leaseId = SetLeasedState(blob, null /* infinite lease */); - blob.BreakLease(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a breaking state for 60 seconds. - /// - /// The blob with the lease. - /// The lease ID of the current (but breaking) lease. - internal static string SetBreakingStateAPM(ICloudBlob blob) - { - string leaseId = SetLeasedStateAPM(blob, null /* infinite lease */); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndBreakLease(result); - } - - return leaseId; - } - -#if TASK - /// - /// Puts the lease on the given blob in a breaking state for 60 seconds. - /// - /// The blob with the lease. - /// The lease ID of the current (but breaking) lease. - internal static string SetBreakingStateTask(ICloudBlob blob) - { - string leaseId = SetLeasedStateTask(blob, null /* infinite lease */); - - blob.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Wait(); - - return leaseId; - } -#endif - - /// - /// Puts the lease on the given blob in a broken state due to the break period expiring. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static string SetTimeBrokenState(ICloudBlob blob) - { - string leaseId = SetLeasedState(blob, null /* infinite lease */); - blob.BreakLease(TimeSpan.FromSeconds(1)); - Thread.Sleep(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to a break period of zero. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static string SetInstantBrokenState(ICloudBlob blob) - { - string leaseId = SetLeasedState(blob, null /* infinite lease */); - blob.BreakLease(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to a break period of zero. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static string SetInstantBrokenStateAPM(ICloudBlob blob) - { - string leaseId = SetLeasedStateAPM(blob, null /* infinite lease */); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = blob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - blob.EndBreakLease(result); - } - - return leaseId; - } - -#if TASK - /// - /// Puts the lease on the given blob in a broken state due to a break period of zero. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static string SetInstantBrokenStateTask(ICloudBlob blob) - { - string leaseId = SetLeasedStateTask(blob, null /* infinite lease */); - blob.BreakLeaseAsync(TimeSpan.Zero).Wait(); - return leaseId; - } -#endif - - /// - /// Puts the lease on the given blob in an expired state. - /// - /// The blob with the lease. - /// The lease ID of the expired lease. - internal static string SetExpiredState(ICloudBlob blob) - { - string leaseId = SetLeasedState(blob, TimeSpan.FromSeconds(15)); - Thread.Sleep(TimeSpan.FromSeconds(17)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in an expired state. - /// - /// The blob with the lease. - /// The lease ID of the expired lease. - internal static string SetExpiredStateAPM(ICloudBlob blob) - { - string leaseId = SetLeasedStateAPM(blob, TimeSpan.FromSeconds(15)); - Thread.Sleep(TimeSpan.FromSeconds(17)); - return leaseId; - } - -#if TASK - /// - /// Puts the lease on the given blob in an expired state. - /// - /// The blob with the lease. - /// The lease ID of the expired lease. - internal static string SetExpiredStateTask(ICloudBlob blob) - { - string leaseId = SetLeasedStateTask(blob, TimeSpan.FromSeconds(15)); - Thread.Sleep(TimeSpan.FromSeconds(17)); - return leaseId; - } -#endif - - /// - /// Puts the lease on the given container in an unleased state (either available or broken). - /// - /// The container with the lease. - internal static void SetUnleasedState(CloudBlobContainer container) - { - if (!container.CreateIfNotExists()) - { - try - { - container.BreakLease(TimeSpan.Zero); - } - catch (StorageException e) - { - if (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseAlreadyBroken || - e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation) - { - } - else - { - throw; - } - } - } - } - - /// - /// Puts the lease on the given container in an unleased state (either available or broken). - /// - /// The container with the lease. - internal static void SetUnleasedStateAPM(CloudBlobContainer container) - { - if (!container.CreateIfNotExists()) - { - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndBreakLease(result); - } - } - catch (StorageException e) - { - if (e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseAlreadyBroken || - e.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation) - { - } - else - { - throw; - } - } - } - } - - /// - /// Puts the lease on the given container in a leased state. - /// - /// The container with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static string SetLeasedState(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - SetUnleasedState(container); - return container.AcquireLease(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given container in a leased state. - /// - /// The container with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static string SetLeasedStateAPM(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - SetUnleasedStateAPM(container); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginAcquireLease(leaseTime, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - return container.EndAcquireLease(result); - } - } - - /// - /// Puts the lease on the given container in a renewed state. - /// - /// The container with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static string SetRenewedState(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = SetLeasedState(container, leaseTime); - container.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a renewed state. - /// - /// The container with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static string SetRenewedStateAPM(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = SetLeasedStateAPM(container, leaseTime); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndRenewLease(result); - return leaseId; - } - } - - /// - /// Puts the lease on the given container in a released state. - /// - /// The container with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static string SetReleasedState(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = SetLeasedState(container, leaseTime); - container.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a released state. - /// - /// The container with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static string SetReleasedStateAPM(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = SetLeasedStateAPM(container, leaseTime); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndReleaseLease(result); - return leaseId; - } - } - - /// - /// Puts the lease on the given container in a breaking state for 60 seconds. - /// - /// The container with the lease. - /// The lease ID of the current (but breaking) lease. - internal static string SetBreakingState(CloudBlobContainer container) - { - string leaseId = SetLeasedState(container, null /* infinite lease */); - container.BreakLease(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a breaking state for 60 seconds. - /// - /// The container with the lease. - /// The lease ID of the current (but breaking) lease. - internal static string SetBreakingStateAPM(CloudBlobContainer container) - { - string leaseId = SetLeasedStateAPM(container, null /* infinite lease */); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndBreakLease(result); - return leaseId; - } - } - - /// - /// Puts the lease on the given container in a broken state due to the break period expiring. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static string SetTimeBrokenState(CloudBlobContainer container) - { - string leaseId = SetLeasedState(container, null /* infinite lease */); - container.BreakLease(TimeSpan.FromSeconds(1)); - Thread.Sleep(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to the break period expiring. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static string SetTimeBrokenStateAPM(CloudBlobContainer container) - { - string leaseId = SetLeasedStateAPM(container, null /* infinite lease */); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginBreakLease(TimeSpan.FromSeconds(1), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndBreakLease(result); - Thread.Sleep(TimeSpan.FromSeconds(2)); - return leaseId; - } - } - - /// - /// Puts the lease on the given container in a broken state due to a break period of zero. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static string SetInstantBrokenState(CloudBlobContainer container) - { - string leaseId = SetLeasedState(container, null /* infinite lease */); - container.BreakLease(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to a break period of zero. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static string SetInstantBrokenStateAPM(CloudBlobContainer container) - { - string leaseId = SetLeasedStateAPM(container, null /* infinite lease */); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = container.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - container.EndBreakLease(result); - return leaseId; - } - } - - /// - /// Puts the lease on the given container in an expired state. - /// - /// The container with the lease. - /// The lease ID of the expired lease. - internal static string SetExpiredState(CloudBlobContainer container) - { - string leaseId = SetLeasedState(container, TimeSpan.FromSeconds(15)); - Thread.Sleep(TimeSpan.FromSeconds(17)); - return leaseId; - } - - /// - /// Puts the lease on the given container in an expired state. - /// - /// The container with the lease. - /// The lease ID of the expired lease. - internal static string SetExpiredStateAPM(CloudBlobContainer container) - { - string leaseId = SetLeasedStateAPM(container, TimeSpan.FromSeconds(15)); - Thread.Sleep(TimeSpan.FromSeconds(17)); - return leaseId; - } - - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobAcquireLeaseSemanticTests() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - SetAvailableState(leasedBlob); - leaseId = leasedBlob.AcquireLease(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - SetAvailableState(leasedBlob); - leaseId = leasedBlob.AcquireLease(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - SetAvailableState(leasedBlob); - leaseId = leasedBlob.AcquireLease(null /* infinite lease */, null /* proposed lease ID */); - this.BlobAcquireRenewLeaseTest(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - SetReleasedState(leasedBlob, null /* infinite lease */); - leaseId = leasedBlob.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId = leasedBlob.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - SetExpiredState(leasedBlob); - leaseId = leasedBlob.AcquireLease(null /* infinite lease */, leaseId); - this.BlobAcquireRenewLeaseTest(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - SetInstantBrokenState(leasedBlob); - leaseId = leasedBlob.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobRenewLeaseSemanticTests() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(15)); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(60)); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.BlobAcquireRenewLeaseTest(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.BlobAcquireRenewLeaseTest(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - this.DeleteAll(); - } - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. (This last feature is necessary for infinite leases.) - /// - /// The blob to test. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal void BlobAcquireRenewLeaseTest(ICloudBlob leasedBlob, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - DateTime beginTime = DateTime.UtcNow; - - bool testOver = false; - do - { - try - { - // Attempt to write to the blob with no lease ID. - leasedBlob.SetMetadata(); - - // The write succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Writes should not succeed while lease is present."); - - // Since the lease has expired, the test is over. - testOver = true; - } - catch (StorageException exception) - { - if (exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Writes should succeed after a lease expires."); - } - - // End the test early if necessary. - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - // Some other error occurred. Rethrow the exception. - throw; - } - } - - // Attempt to read from the blob. This should always succeed. - leasedBlob.FetchAttributes(); - - // Wait 1 second before trying again. - if (!testOver) - { - Thread.Sleep(TimeSpan.FromSeconds(1)); - } - } - while (!testOver); - - // The lease expired. Write to and read from the blob once more. - leasedBlob.SetMetadata(); - leasedBlob.FetchAttributes(); - } - - [TestMethod] - [Description("Test blob leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeaseInvalidInputTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CreateBlob(leasedBlob); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(TimeSpan.FromSeconds(1), null /* proposed lease ID */), - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(TimeSpan.FromSeconds(14), null /* proposed lease ID */), - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(TimeSpan.FromSeconds(61), null /* proposed lease ID */), - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(null /* infinite lease */, invalidLeaseId), - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the blob is leased - leaseId = leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(null /* access condition */), - "renew with null access condition"); - - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateEmptyCondition()), - "renew with no lease ID"); - - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, null /* access condition */), - "change with null access condition"); - - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateEmptyCondition()), - "change with no lease ID"); - - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with no proposed lease ID"); - - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(null /* access condition */), - "release with null access condition"); - - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateEmptyCondition()), - "release with no lease ID"); - - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(TimeSpan.FromSeconds(-1)), - "break with negative break time"); - - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(TimeSpan.FromSeconds(61)), - "break with too large break time", - HttpStatusCode.BadRequest); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobAcquireLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - SetAvailableState(leasedBlob); - leaseId = leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - leaseId2 = leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(null /* infinite lease */, leaseId), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.AcquireLease(null /* infinite lease */, leaseId); - leasedBlob.AcquireLease(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - leasedBlob.AcquireLease(null /* infinite lease */, leaseId); - leasedBlob.AcquireLease(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - SetAvailableState(leasedBlob); - leaseId = leasedBlob.AcquireLease(null /* infinite lease */, null /* proposed lease ID */); - TestHelper.ExpectedException( - () => leasedBlob.AcquireLease(null /* infinite lease */, null /* proposed lease ID */), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobAcquireLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - SetAvailableStateAPM(leasedBlob); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedBlob.EndAcquireLease(result); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndAcquireLease(result); - - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingStateAPM(leasedBlob); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in released state (same ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in released state (new ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire with no proposed ID (non-idempotent) - SetAvailableStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - } - - // Delete the blob - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobAcquireLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - SetAvailableStateAPM(leasedBlob); - IAsyncResult result; - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedBlob.EndAcquireLease(result); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndAcquireLease(result); - - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingStateAPM(leasedBlob); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in released state (same ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire the lease while in released state (new ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - - // Acquire with no proposed ID (non-idempotent) - SetAvailableStateAPM(leasedBlob); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndAcquireLease(result); - result = leasedBlob.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndAcquireLease(result), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - } - // Delete the blob - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobAcquireLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - SetAvailableStateTask(leasedBlob); - - leaseId = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - - leaseId2 = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - SetLeasedStateTask(leasedBlob, null /* infinite lease */); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingStateTask(leasedBlob); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - SetBreakingStateTask(leasedBlob); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in broken state (new ID), make idempotent call - SetInstantBrokenStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - - // Acquire the lease while in released state (same ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in released state (new ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - SetReleasedStateTask(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, context).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, context).Wait(); - - // Acquire with no proposed ID (non-idempotent) - SetAvailableStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, context).Wait(); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, context), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - - // Delete the blob - this.DeleteAllTask(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobAcquireLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - SetAvailableStateTask(leasedBlob); - - leaseId = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - leaseId2 = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingStateTask(leasedBlob); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingStateTask(leasedBlob); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - - // Acquire the lease while in released state (same ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in released state (new ID), make idempotent call. Also, use the other overload for BeginAcquireLease. - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, context).Wait(); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, context).Wait(); - - // Acquire with no proposed ID (non-idempotent) - SetAvailableStateTask(leasedBlob); - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, context).Wait(); - - TestHelper.ExpectedExceptionTask( - leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, context), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - this.DeleteAllTask(); - } -#endif - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobRenewLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Renew lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredState(leasedBlob); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = SetExpiredState(leasedBlob); - string content = DownloadText(leasedBlob, Encoding.UTF8); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = SetExpiredState(leasedBlob); - leasedBlob.SetMetadata(); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(60)); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobRenewLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Renew lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredState(leasedBlob); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = SetExpiredState(leasedBlob); - string content = DownloadText(leasedBlob, Encoding.UTF8); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = SetExpiredState(leasedBlob); - leasedBlob.SetMetadata(); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(60)); - leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedState(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobRenewLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Renew lease in available state - SetAvailableStateAPM(leasedBlob); - IAsyncResult result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew expired lease after read - leaseId = SetExpiredStateAPM(leasedBlob); - string content = DownloadText(leasedBlob, Encoding.UTF8); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew expired lease after write - leaseId = SetExpiredStateAPM(leasedBlob); - leasedBlob.SetMetadata(); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobRenewLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Renew lease in available state - SetAvailableStateAPM(leasedBlob); - IAsyncResult result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew expired lease after read - leaseId = SetExpiredStateAPM(leasedBlob); - string content = DownloadText(leasedBlob, Encoding.UTF8); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew expired lease after write - leaseId = SetExpiredStateAPM(leasedBlob); - leasedBlob.SetMetadata(); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndRenewLease(result); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedStateAPM(leasedBlob, TimeSpan.FromSeconds(60)); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndRenewLease(result), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - } - -#if TASK - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobRenewLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Renew lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredStateTask(leasedBlob); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after read - leaseId = SetExpiredStateTask(leasedBlob); - string content = DownloadTextTask(leasedBlob, Encoding.UTF8); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after write - leaseId = SetExpiredStateTask(leasedBlob); - leasedBlob.SetMetadataAsync().Wait(); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, new OperationContext()), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAllTask(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobRenewLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Renew lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredStateTask(leasedBlob); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after read - leaseId = SetExpiredStateTask(leasedBlob); - string content = DownloadTextTask(leasedBlob, Encoding.UTF8); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after write - leaseId = SetExpiredStateTask(leasedBlob); - leasedBlob.SetMetadataAsync().Wait(); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedStateTask(leasedBlob, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, new OperationContext()), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAllTask(); - } -#endif - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobChangeLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2)), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobChangeLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2)), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobChangeLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndChangeLease(result); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndChangeLease(result); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - - // Change lease (wrong lease specified) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID). Use the other overload for BeginChangeLease. - leaseId = SetBreakingStateAPM(leasedBlob); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedBlob); - result = leasedBlob.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobChangeLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndChangeLease(result); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndChangeLease(result); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - - // Change lease (wrong lease specified) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedBlob.EndChangeLease(result); - - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID). Use the other overload for BeginChangeLease. - leaseId = SetBreakingStateAPM(leasedBlob); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedBlob); - result = leasedBlob.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndChangeLease(result), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - } - -#if TASK - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobChangeLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()).Result; - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, new OperationContext()).Result; - - this.DeleteAllTask(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobChangeLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Change lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()).Result; - leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, new OperationContext()).Result; - - this.DeleteAllTask(); - } -#endif - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobReleaseLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = SetBreakingState(leasedBlob); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReleaseLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = SetBreakingState(leasedBlob); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = SetBreakingState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobReleaseLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release lease in released state (old lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease), Use overload for BeginReleaseLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease), Use overload for BeginReleaseLease. - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release breaking lease (wrong lease), Use overload for BeginReleaseLease. - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease), Use overload for BeginReleaseLease. - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReleaseLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release lease in released state (old lease) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease), Use overload for BeginReleaseLease. - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease), Use overload for BeginReleaseLease. - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release breaking lease (wrong lease), Use overload for BeginReleaseLease. - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease), Use overload for BeginReleaseLease. - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndReleaseLease(result); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - - TestHelper.ExpectedException( - () => leasedBlob.EndReleaseLease(result), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - } - -#if TASK - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobReleaseLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()).Wait(); - - this.DeleteAllTask(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobReleaseLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Release lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()); - - this.DeleteAllTask(); - } -#endif - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobBreakLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = SetBreakingState(leasedBlob); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingState(leasedBlob); - leasedBlob.BreakLease(null /* default break time */); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(null /* default break time */); - - // Break instant broken lease (default break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(null /* default break time */); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(null /* default break time */), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobBreakLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableState(leasedBlob); - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = SetBreakingState(leasedBlob); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingState(leasedBlob); - leasedBlob.BreakLease(null /* default break time */); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLease(null /* default break time */); - - // Break instant broken lease (default break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(null /* default break time */); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenState(leasedBlob); - leasedBlob.BreakLease(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedBlob.BreakLease(null /* default break time */), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobBreakLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndBreakLease(result), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(1), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - - // Break breaking lease (zero break time) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(null /* default break time */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break finite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(null /* default break time */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (default break time). Use the other overload for BeginBreakLease. - leaseId = SetInstantBrokenStateAPM(leasedBlob); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginBreakLease(null /* default break time */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(1), null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break released lease (default break time) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(null /* default break time */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndBreakLease(result), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobBreakLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableStateAPM(leasedBlob); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndBreakLease(result), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(1), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - - // Break breaking lease (zero break time) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(null /* default break time */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break finite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedBlob.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedStateAPM(leasedBlob, TimeSpan.FromSeconds(50)); - result = leasedBlob.BeginBreakLease(null /* default break time */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (default break time). Use the other overload for BeginBreakLease. - leaseId = SetInstantBrokenStateAPM(leasedBlob); - OperationContext context = new OperationContext(); - result = leasedBlob.BeginBreakLease(null /* default break time */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.FromSeconds(1), null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - result = leasedBlob.BeginBreakLease(TimeSpan.Zero, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedBlob.EndBreakLease(result); - - // Break released lease (default break time) - leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); - result = leasedBlob.BeginBreakLease(null /* default break time */, null, null, context, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedBlob.EndBreakLease(result), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - } - -#if TASK - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobBreakLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableStateTask(leasedBlob); - - TestHelper.ExpectedExceptionTask( - leasedBlob.BreakLeaseAsync(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(null /* default break period */).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)).Result; - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Result; - - // Break breaking lease (zero break time) - leaseId = SetBreakingStateTask(leasedBlob); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(null /* default break time */).Wait(); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Wait(); - - // Break finite lease (zero break time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leasedBlob.BreakLeaseAsync(null /* default break time */).Wait(); - - // Break instant broken lease (default break time). Use the other overload for BeginBreakLease. - leaseId = SetInstantBrokenStateTask(leasedBlob); - OperationContext context = new OperationContext(); - leasedBlob.BreakLeaseAsync(null /* default break time */, null, null, context).Wait(); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1), null, null, context).Wait(); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenStateAPM(leasedBlob); - leasedBlob.BreakLeaseAsync(TimeSpan.Zero, null, null, context).Wait(); - - // Break released lease (default break time) - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.BreakLeaseAsync(null /* default break time */, null, null, context), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAllTask(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobBreakLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - - // Break lease in available state - SetAvailableStateTask(leasedBlob); - TestHelper.ExpectedExceptionTask( - leasedBlob.BreakLeaseAsync(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(null /* default break period */).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)).Result; - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Result; - - // Break breaking lease (zero break time) - leaseId = SetBreakingStateTask(leasedBlob); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(null /* default break time */).Wait(); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Result; - - // Break finite lease (zero break time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedStateTask(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = leasedBlob.BreakLeaseAsync(null /* default break time */).Result; - - // Break instant broken lease (default break time) - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(null /* default break time */).Wait(); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)).Wait(); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenStateTask(leasedBlob); - leasedBlob.BreakLeaseAsync(TimeSpan.Zero, null, null, null).Wait(); - - // Break released lease (default break time) - leaseId = SetReleasedStateTask(leasedBlob, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedBlob.BreakLeaseAsync(null /* default break time */), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAllTask(); - } -#endif - - [TestMethod] - [Description("Tests blob write and delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedWriteTests() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob sourceBlob = leasedBlob.Container.GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // Verify that blob creation fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // BlobCreateExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create blob using a lease"); - - // From available state, verify that writes/deletes that pass a lease fail if none is present. - SetAvailableState(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write blob using a lease when no lease is held"); - - // From leased state, verify that writes/deletes without a lease do not succeed. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobWriteExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write blob using no lease when a lease is held"); - - // From leased state, verify that writes/deletes with the wrong lease fail. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write blob using a lease when a different lease is held"); - - // From leased state, verify that writes/deletes with the right lease succeed. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobWriteExpectLeaseSuccess(leasedBlob, sourceBlob, testAccessCondition); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Tests blob write and delete APIs in the presence of a lease using APM.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedWriteTestsAPM() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob sourceBlob = leasedBlob.Container.GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // Verify that blob creation fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // BlobCreateExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create blob using a lease"); - - // From available state, verify that writes/deletes that pass a lease fail if none is present. - SetAvailableStateAPM(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailureAPM(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write blob using a lease when no lease is held"); - - // From leased state, verify that writes/deletes without a lease do not succeed. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobWriteExpectLeaseFailureAPM(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write blob using no lease when a lease is held"); - - // From leased state, verify that writes/deletes with the wrong lease fail. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailureAPM(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write blob using a lease when a different lease is held"); - - // From leased state, verify that writes/deletes with the right lease succeed. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobWriteExpectLeaseSuccessAPM(leasedBlob, sourceBlob, testAccessCondition); - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Tests blob write and delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedWriteTestsTask() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob sourceBlob = leasedBlob.Container.GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // Verify that blob creation fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // BlobCreateExpectLeaseFailureTask(leasedBlob, sourceBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create blob using a lease"); - - // From available state, verify that writes/deletes that pass a lease fail if none is present. - SetAvailableStateTask(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailureTask(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write blob using a lease when no lease is held"); - - // From leased state, verify that writes/deletes without a lease do not succeed. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobWriteExpectLeaseFailureTask(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write blob using no lease when a lease is held"); - - // From leased state, verify that writes/deletes with the wrong lease fail. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobWriteExpectLeaseFailureTask(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write blob using a lease when a different lease is held"); - - // From leased state, verify that writes/deletes with the right lease succeed. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobWriteExpectLeaseSuccessTask(leasedBlob, sourceBlob, testAccessCondition); - - this.DeleteAllTask(); - } -#endif - - /// - /// Test blob write and creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobWriteExpectLeaseFailure(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - this.BlobCreateExpectLeaseFailure(testBlob, sourceBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - TestHelper.ExpectedException( - () => testBlob.SetMetadata(testAccessCondition, null /* options */), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testBlob.SetProperties(testAccessCondition, null /* options */), - description + " (Set Properties)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testBlob.Delete(DeleteSnapshotsOption.None, testAccessCondition, null /* options */), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test blob write and creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobWriteExpectLeaseFailureAPM(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - this.BlobCreateExpectLeaseFailure(testBlob, sourceBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testBlob.BeginSetMetadata(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndSetMetadata(result), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - - result = testBlob.BeginSetProperties(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndSetProperties(result), - description + " (Set Properties)", - expectedStatusCode, - expectedErrorCode); - - result = testBlob.BeginDelete(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndDelete(result), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - } - -#if TASK - /// - /// Test blob write and creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobWriteExpectLeaseFailureTask(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - this.BlobCreateExpectLeaseFailureTask(testBlob, sourceBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - TestHelper.ExpectedExceptionTask( - testBlob.SetMetadataAsync(testAccessCondition, null /* options */, new OperationContext()), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedExceptionTask( - testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, new OperationContext()), - description + " (Set Properties)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedExceptionTask( - testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, new OperationContext()), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } -#endif - - /// - /// Test blob creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobCreateExpectLeaseFailure(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => UploadText(testBlob, "No Dice", Encoding.UTF8, testAccessCondition, null /* options */), - description + " (Upload Text)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testBlob.StartCopyFromBlob(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */), - description + " (Copy From)", - expectedStatusCode, - expectedErrorCode); - - Stream stream = testBlob.OpenWrite(testAccessCondition, null /* options */); - TestHelper.ExpectedException( - () => - { - stream.WriteByte(0); - stream.Flush(); - }, - description + " (Write Stream)", - expectedStatusCode, - expectedErrorCode); - } - -#if TASK - /// - /// Test blob creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobCreateExpectLeaseFailureTask(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => UploadTextTask(testBlob, "No Dice", Encoding.UTF8, testAccessCondition, null /* options */), - description + " (Upload Text)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedExceptionTask( - testBlob.StartCopyFromBlobAsync(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, new OperationContext()), - description + " (Copy From)", - expectedStatusCode, - expectedErrorCode); - - Stream stream = testBlob.OpenWriteAsync(testAccessCondition, null /* options */, new OperationContext()).Result; - TestHelper.ExpectedException( - () => - { - stream.WriteByte(0); - stream.Flush(); - }, - description + " (Write Stream)", - expectedStatusCode, - expectedErrorCode); - } -#endif - - /// - /// Test blob writing, expecting success. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The access condition to use. - private void BlobWriteExpectLeaseSuccess(CloudBlockBlob testBlob, ICloudBlob sourceBlob, AccessCondition testAccessCondition) - { - testBlob.SetMetadata(testAccessCondition, null /* options */); - testBlob.SetProperties(testAccessCondition, null /* options */); - UploadText(testBlob, "No Problem", Encoding.UTF8, testAccessCondition, null /* options */); - testBlob.StartCopyFromBlob(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */); - - while (testBlob.CopyState.Status == CopyStatus.Pending) - { - Thread.Sleep(1000); - testBlob.FetchAttributes(); - } - - Stream stream = testBlob.OpenWrite(testAccessCondition, null /* options */); - stream.WriteByte(0); - stream.Flush(); - - testBlob.Delete(DeleteSnapshotsOption.None, testAccessCondition, null /* options */); - } - - /// - /// Test blob writing, expecting success. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The access condition to use. - private void BlobWriteExpectLeaseSuccessAPM(CloudBlockBlob testBlob, ICloudBlob sourceBlob, AccessCondition testAccessCondition) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testBlob.BeginSetMetadata(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndSetMetadata(result); - - result = testBlob.BeginSetProperties(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndSetProperties(result); - - UploadTextAPM(testBlob, "No Problem", Encoding.UTF8, testAccessCondition, null /* options */); - result = testBlob.BeginStartCopyFromBlob(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, null /* operationContext */, ar=>waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndStartCopyFromBlob(result); - - while (testBlob.CopyState.Status == CopyStatus.Pending) - { - Thread.Sleep(1000); - result = testBlob.BeginFetchAttributes(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndFetchAttributes(result); - } - - result = testBlob.BeginOpenWrite(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Stream stream = testBlob.EndOpenWrite(result); - stream.WriteByte(0); - stream.Flush(); - - result = testBlob.BeginDelete(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndDelete(result); - } - } - -#if TASK - /// - /// Test blob writing, expecting success. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The access condition to use. - private void BlobWriteExpectLeaseSuccessTask(CloudBlockBlob testBlob, ICloudBlob sourceBlob, AccessCondition testAccessCondition) - { - testBlob.SetMetadataAsync(testAccessCondition, null /* options */, new OperationContext()).Wait(); - testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, new OperationContext()).Wait(); - UploadTextTask(testBlob, "No Problem", Encoding.UTF8, testAccessCondition, null /* options */, new OperationContext()); - testBlob.StartCopyFromBlobAsync( - TestHelper.Defiddler(sourceBlob.Uri), - null /* source access condition */, - testAccessCondition, - null /* options */, - new OperationContext()).Wait(); - - while (testBlob.CopyState.Status == CopyStatus.Pending) - { - Thread.Sleep(1000); - testBlob.FetchAttributesAsync().Wait(); - } - - Stream stream = testBlob.OpenWriteAsync(testAccessCondition, null /* options */, new OperationContext()).Result; - stream.WriteByte(0); - stream.Flush(); - - testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, new OperationContext()); - } -#endif - - [TestMethod] - [Description("Tests blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedReadTests() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob targetBlob = leasedBlob.Container.GetBlockBlobReference("TargetBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // From available state, verify that reads that pass a lease fail if none is present - SetAvailableState(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailure(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read blob using a lease when no lease is held"); - - // Verify that reads without a lease succeed. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailure(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Tests blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedReadTestsAPM() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob targetBlob = leasedBlob.Container.GetBlockBlobReference("TargetBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // From available state, verify that reads that pass a lease fail if none is present - SetAvailableStateAPM(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailureAPM(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read blob using a lease when no lease is held"); - - // Verify that reads without a lease succeed. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobReadExpectLeaseSuccessAPM(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailureAPM(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobReadExpectLeaseSuccessAPM(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Tests blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeasedReadTestsTask() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob targetBlob = leasedBlob.Container.GetBlockBlobReference("TargetBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // From available state, verify that reads that pass a lease fail if none is present - SetAvailableStateTask(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailureTask(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read blob using a lease when no lease is held"); - - // Verify that reads without a lease succeed. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - this.BlobReadExpectLeaseSuccessTask(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - this.BlobReadExpectLeaseFailureTask(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - this.BlobReadExpectLeaseSuccessTask(leasedBlob, testAccessCondition); - - this.DeleteAllTask(); - } -#endif - - /// - /// Test blob reads, expecting lease failure. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobReadExpectLeaseFailure(CloudBlockBlob testBlob, CloudBlockBlob targetBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - TestHelper.ExpectedException( - () => testBlob.FetchAttributes(testAccessCondition, null /* options */), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - TestHelper.ExpectedException( - () => testBlob.CreateSnapshot(null /* metadata */, testAccessCondition, null /* options */), - description + " (Create Snapshot)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => DownloadText(testBlob, Encoding.UTF8, testAccessCondition, null /* options */), - description + " (Download Text)", - expectedStatusCode, - expectedErrorCode); - - TestHelper.ExpectedException( - () => testBlob.OpenRead(testAccessCondition, null /* options */), - description + " (Read Stream)", - expectedStatusCode/*, - expectedErrorCode*/); - } - - /// - /// Test blob reads, expecting lease failure. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobReadExpectLeaseFailureAPM(CloudBlockBlob testBlob, CloudBlockBlob targetBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testBlob.BeginFetchAttributes(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndFetchAttributes(result), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - result = testBlob.BeginCreateSnapshot(null /* metadata */, testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndCreateSnapshot(result), - description + " (Create Snapshot)", - expectedStatusCode, - expectedErrorCode); - - TestHelper.ExpectedException( - () => DownloadTextAPM(testBlob, Encoding.UTF8, testAccessCondition, null /* options */), - description + " (Download Text)", - expectedStatusCode, - expectedErrorCode); - - result = testBlob.BeginOpenRead(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testBlob.EndOpenRead(result), - description + " (Read Stream)", - expectedStatusCode/*, - expectedErrorCode*/); - } - } - -#if TASK - /// - /// Test blob reads, expecting lease failure. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlobReadExpectLeaseFailureTask(CloudBlockBlob testBlob, CloudBlockBlob targetBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - TestHelper.ExpectedExceptionTask( - testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, new OperationContext()), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - TestHelper.ExpectedExceptionTask( - testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, new OperationContext()), - description + " (Create Snapshot)", - expectedStatusCode, - expectedErrorCode); - - TestHelper.ExpectedException( - () => DownloadTextTask(testBlob, Encoding.UTF8, testAccessCondition, null /* options */), - description + " (Download Text)", - expectedStatusCode, - expectedErrorCode); - - TestHelper.ExpectedExceptionTask( - testBlob.OpenReadAsync(testAccessCondition, null /* options */, new OperationContext()), - description + " (Read Stream)", - expectedStatusCode/*, - expectedErrorCode*/); - } -#endif - - /// - /// Test blob reads, expecting success. - /// - /// The blob to test. - /// The access condition to use. - private void BlobReadExpectLeaseSuccess(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - testBlob.FetchAttributes(testAccessCondition, null /* options */); - testBlob.CreateSnapshot(null /* metadata */, testAccessCondition, null /* options */).Delete(); - DownloadText(testBlob, Encoding.UTF8, testAccessCondition, null /* options */); - - Stream stream = testBlob.OpenRead(testAccessCondition, null /* options */); - stream.ReadByte(); - } - - /// - /// Test blob reads, expecting success. - /// - /// The blob to test. - /// The access condition to use. - private void BlobReadExpectLeaseSuccessAPM(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testBlob.BeginFetchAttributes(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndFetchAttributes(result); - - result = testBlob.BeginCreateSnapshot(null /* metadata */, testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testBlob.EndCreateSnapshot(result).Delete(); - - DownloadTextAPM(testBlob, Encoding.UTF8, testAccessCondition, null /* options */); - - result = testBlob.BeginOpenRead(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Stream stream = testBlob.EndOpenRead(result); - stream.ReadByte(); - } - } - -#if TASK - /// - /// Test blob reads, expecting success. - /// - /// The blob to test. - /// The access condition to use. - private void BlobReadExpectLeaseSuccessTask(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, new OperationContext()); - testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, new OperationContext()).Result.Delete(); - DownloadTextTask(testBlob, Encoding.UTF8, testAccessCondition, null /* options */); - - Stream stream = testBlob.OpenReadAsync(testAccessCondition, null /* options */, new OperationContext()).Result; - stream.ReadByte(); - } -#endif - - [TestMethod] - [Description("Tests page blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobLeasedWriteTests() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - leasedBlob.Container.Create(); - - // Verify that creating the page blob fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // PageBlobCreateExpectLeaseFailure(leasedBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create page blob using a lease"); - - // Create a page blob - testAccessCondition.LeaseId = null; - PageBlobCreateExpectSuccess(leasedBlob, testAccessCondition); - - // From available state, verify that writing the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - PageBlobWriteExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = leasedBlob.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - PageBlobWriteExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write page blob with no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - PageBlobWriteExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write page blob using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - PageBlobWriteExpectSuccess(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - - /// - /// Test page blob creation, expecting lease failure. - /// - /// The page blob to test. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void PageBlobCreateExpectLeaseFailure(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => testBlob.Create(8 * 512, testAccessCondition, null /* options */), - description + " (Create Page Blob)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob writes, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void PageBlobWriteExpectLeaseFailure(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - PageBlobCreateExpectLeaseFailure(testBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - TestHelper.ExpectedException( - () => testBlob.ClearPages(512, 512, testAccessCondition, null /* options */), - description + " (Clear Pages)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testBlob.WritePages(pageStream, 512, null, testAccessCondition, null /* options */), - description + " (Write Pages)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob creation, expecting success. - /// - /// The page blob. - /// The test access condition. - private void PageBlobCreateExpectSuccess(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - testBlob.Create(8 * 512, testAccessCondition, null /* options */); - } - - /// - /// Test page blob writes, expecting success. - /// - /// The page blob. - /// The access condition to use. - private void PageBlobWriteExpectSuccess(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - byte[] buffer = new byte[4 * 512]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - testBlob.ClearPages(512, 512, testAccessCondition, null /* options */); - testBlob.WritePages(pageStream, 512, null, testAccessCondition, null /* options */); - } - - [TestMethod] - [Description("Tests page blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void PageBlobLeasedReadTests() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - leasedBlob.Container.Create(); - - // Create a page blob - testAccessCondition.LeaseId = null; - PageBlobCreateExpectSuccess(leasedBlob, testAccessCondition); - - // Verify that reading the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - PageBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = leasedBlob.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease succeed. - testAccessCondition.LeaseId = null; - PageBlobReadExpectSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - PageBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read page blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - PageBlobReadExpectSuccess(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - - /// - /// Test page blob reads, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void PageBlobReadExpectLeaseFailure(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => testBlob.GetPageRanges(null /* offset */, null /* length */, testAccessCondition, null /* options */), - description + "(Get Page Ranges)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob reads, expecting success. - /// - /// The page blob. - /// The access condition to use. - private void PageBlobReadExpectSuccess(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - testBlob.GetPageRanges(null /* offset */, null /* length */, testAccessCondition, null /* options */); - } - - [TestMethod] - [Description("Tests block blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobLeasedWriteTests() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - leasedBlob.Container.Create(); - - // Verify that creating the first block fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testOptions.LeaseId = fakeLease; - // BlockCreateExpectLeaseFailure(leasedBlob, testOptions, BlobErrorCodeStrings.LeaseNotPresent, "create initial block using a lease"); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(BlockCreateExpectSuccess(leasedBlob, testAccessCondition)); - - // Verify that creating an additional block fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - BlockCreateExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "create additional block using a lease"); - - // Verify that block list writes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - BlockBlobWriteExpectLeaseFailure(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "set initial block list using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = leasedBlob.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - BlockCreateExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - BlockBlobWriteExpectLeaseFailure(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "set initial block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - BlockCreateExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - BlockBlobWriteExpectLeaseFailure(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "set initial block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - blockList.Add(BlockCreateExpectSuccess(leasedBlob, testAccessCondition)); - BlockBlobWriteExpectSuccess(leasedBlob, blockList, testAccessCondition); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = null; - BlockCreateExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - BlockBlobWriteExpectLeaseFailure(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "update block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = fakeLease; - BlockCreateExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - BlockBlobWriteExpectLeaseFailure(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "update block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed, with the block list already set. - testAccessCondition.LeaseId = leaseId; - blockList.Add(BlockCreateExpectSuccess(leasedBlob, testAccessCondition)); - BlockBlobWriteExpectSuccess(leasedBlob, blockList, testAccessCondition); - - this.DeleteAll(); - } - - /// - /// Test block creation, expecting lease failure. - /// - /// The block blob in which to attempt to create a block. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlockCreateExpectLeaseFailure(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => BlockCreate(testBlob, testAccessCondition), - description + " (Put Block)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob creation (block list setting), expecting lease failure. - /// - /// The block blob. - /// An appropriate block list to set. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlockBlobWriteExpectLeaseFailure(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => testBlob.PutBlockList(blockList, testAccessCondition, null /* options */), - description + " (Put Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block creation, expecting success. - /// - /// The block blob. - /// The test access condition. - /// The name of the new block. - private string BlockCreateExpectSuccess(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - return BlockCreate(testBlob, testAccessCondition); - } - - /// - /// Create a block with a random name. - /// - /// The block blob. - /// The access condition. - /// The name of the new block. - private string BlockCreate(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - string blockId = Guid.NewGuid().ToString("N"); - Stream blockData = new MemoryStream(buffer); - testBlob.PutBlock(blockId, blockData, null /* content MD5 */, testAccessCondition, null /* options */); - - return blockId; - } - - /// - /// Test block blob creation (set block list), expecting success. - /// - /// The block blob. - /// The block list to set. - /// The access condition to use. - private void BlockBlobWriteExpectSuccess(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition) - { - testBlob.PutBlockList(blockList, testAccessCondition, null /* options */); - } - - [TestMethod] - [Description("Tests block blob read APIs in the presence of a lease on a blob with no block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobLeasedReadTestsWithoutList() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - leasedBlob.Container.Create(); - - // Create a block - testAccessCondition.LeaseId = null; - BlockCreateExpectSuccess(leasedBlob, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - BlockBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = leasedBlob.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - BlockBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Tests block blob read APIs in the presence of a lease on a blob with a block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlockBlobLeasedReadTestsWithList() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - leasedBlob.Container.Create(); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(BlockCreateExpectSuccess(leasedBlob, testAccessCondition)); - - // Put the block list - testAccessCondition.LeaseId = null; - BlockBlobWriteExpectSuccess(leasedBlob, blockList, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - BlockBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = leasedBlob.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - BlockBlobReadExpectLeaseFailure(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - BlockBlobReadExpectLeaseSuccess(leasedBlob, testAccessCondition); - - this.DeleteAll(); - } - - /// - /// Test block blob reads, expecting lease failure. - /// - /// The block blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void BlockBlobReadExpectLeaseFailure(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => testBlob.DownloadBlockList(BlockListingFilter.Committed, testAccessCondition, null /* options */), - description + "(Download Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob reads, expecting success. - /// - /// The block blob. - /// The access condition to use. - private void BlockBlobReadExpectLeaseSuccess(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - testBlob.DownloadBlockList(BlockListingFilter.Committed, testAccessCondition, null /* options */); - } - - [TestMethod] - [Description("Test reading the blob lease status and state after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobLeaseStatusTest() - { - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Check uninitialized lease status - SetAvailableState(leasedBlob); - Assert.AreEqual(LeaseStatus.Unspecified, leasedBlob.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedBlob.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedBlob.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - SetAvailableState(leasedBlob); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - SetLeasedState(leasedBlob, null /* infinite lease */); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - SetLeasedState(leasedBlob, TimeSpan.FromSeconds(45)); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - SetRenewedState(leasedBlob, null /* infinite lease */); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - SetRenewedState(leasedBlob, TimeSpan.FromSeconds(45)); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); - leasedBlob.ChangeLease(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = SetLeasedState(leasedBlob, TimeSpan.FromSeconds(45)); - leasedBlob.ChangeLease(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - SetReleasedState(leasedBlob, null /* infinite lease */); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - SetBreakingState(leasedBlob); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - SetTimeBrokenState(leasedBlob); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - SetTimeBrokenState(leasedBlob); - leasedBlob.AcquireLease(null /* infinite lease */, null /*proposed lease ID */); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - SetInstantBrokenState(leasedBlob); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - SetExpiredState(leasedBlob); - this.CheckLeaseStatus(leasedBlob, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - this.DeleteAll(); - } - - /// - /// Checks the lease status of a blob, both from its attributes and from a blob listing. - /// - /// The blob to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private void CheckLeaseStatus( - ICloudBlob blob, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - blob.FetchAttributes(); - Assert.AreEqual(expectedStatus, blob.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, blob.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, blob.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - BlobProperties propertiesInListing = (from ICloudBlob b in blob.Container.ListBlobs( - blob.Name, - true /* use flat blob listing */, - BlobListingDetails.None, - null /* options */) - where b.Name == blob.Name - select b.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListBlobs)"); - } - - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseSemanticTests() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLease(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLease(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLease(null /* infinite lease */, null /* proposed lease ID */); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-4"); // make sure we use a new container - SetReleasedState(leasedContainer, null /* infinite lease */); - leaseId = leasedContainer.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-5"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId = leasedContainer.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-6"); // make sure we use a new container - SetExpiredState(leasedContainer); - leaseId = leasedContainer.AcquireLease(null /* infinite lease */, leaseId); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-7"); // make sure we use a new container - SetInstantBrokenState(leasedContainer); - leaseId = leasedContainer.AcquireLease(TimeSpan.FromSeconds(15), leaseId); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations with APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseSemanticTestsAPM() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - SetUnleasedStateAPM(leasedContainer); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = leasedContainer.BeginAcquireLease(TimeSpan.FromSeconds(15), null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - SetUnleasedStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(TimeSpan.FromSeconds(60), null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - SetUnleasedStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-4"); // make sure we use a new container - SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginAcquireLease(TimeSpan.FromSeconds(15), leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-5"); // make sure we use a new container - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginAcquireLease(TimeSpan.FromSeconds(15), leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-6"); // make sure we use a new container - SetExpiredState(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-7"); // make sure we use a new container - SetInstantBrokenState(leasedContainer); - result = leasedContainer.BeginAcquireLease(TimeSpan.FromSeconds(15), leaseId, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - } - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseSemanticTestsTask() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), null /* proposed lease ID */).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null /* proposed lease ID */).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-4"); // make sure we use a new container - SetReleasedState(leasedContainer, null /* infinite lease */); - leaseId = leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-5"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId = leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-6"); // make sure we use a new container - SetExpiredState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-7"); // make sure we use a new container - SetInstantBrokenState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId, null, null, null).Result; - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - this.DeleteAll(); - } -#endif - - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseSemanticTests() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(15)); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseSemanticTestsAPM() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - - CloudBlobContainer leasedContainer; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(15)); - IAsyncResult result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(60)); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - } - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseSemanticTestsTask() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(15)); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - this.ContainerAcquireRenewLeaseTest(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, null).Wait(); - this.ContainerAcquireRenewLeaseTest(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - this.DeleteAll(); - } -#endif - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. - /// - /// The container. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal void ContainerAcquireRenewLeaseTest(CloudBlobContainer leasedContainer, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - DateTime beginTime = DateTime.UtcNow; - - while (true) - { - try - { - // Attempt to delete the container with no lease ID. - leasedContainer.Delete(); - - // The delete succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Deletes should not succeed while lease is present."); - - // Since the lease has expired (and the container was deleted), the test is over. - return; - } - catch (StorageException exception) - { - if (exception.RequestInformation.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Deletes should succeed after a lease expires."); - } - - // End the test early if necessary - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - throw; - } - } - - // Attempt to write to and read from the container. This should always succeed. - leasedContainer.SetMetadata(); - leasedContainer.FetchAttributes(); - - // Wait 1 second before trying again. - Thread.Sleep(TimeSpan.FromSeconds(1)); - } - } - - [TestMethod] - [Description("Test container leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeaseInvalidInputTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - leasedContainer.Create(); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(TimeSpan.FromSeconds(1), null /* proposed lease ID */), - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(TimeSpan.FromSeconds(14), null /* proposed lease ID */), - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(TimeSpan.FromSeconds(61), null /* proposed lease ID */), - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(null /* infinite lease */, invalidLeaseId), - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the container is leased - leaseId = leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(null /* access condition */), - "renew with null access condition"); - - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateEmptyCondition()), - "renew with no lease ID"); - - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, null /* access condition */), - "change with null access condition"); - - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, AccessCondition.GenerateEmptyCondition()), - "change with no lease ID"); - - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with no proposed lease ID"); - - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(null /* access condition */), - "release with null access condition"); - - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateEmptyCondition()), - "release with no lease ID"); - - TestHelper.ExpectedException( - () => leasedContainer.BreakLease(TimeSpan.FromSeconds(-1)), - "break with negative break time"); - - TestHelper.ExpectedException( - () => leasedContainer.BreakLease(TimeSpan.FromSeconds(61)), - "break with too large break time", - HttpStatusCode.BadRequest); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Acquire the lease while in available state, make idempotent call - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - leaseId2 = leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(null /* infinite lease */, leaseId), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.AcquireLease(null /* infinite lease */, leaseId); - leasedContainer.AcquireLease(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - leasedContainer.AcquireLease(null /* infinite lease */, leaseId); - leasedContainer.AcquireLease(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLease(null /* infinite lease */, null /* proposed lease ID */); - TestHelper.ExpectedException( - () => leasedContainer.AcquireLease(null /* infinite lease */, null /* proposed lease ID */), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states in APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Acquire the lease while in available state, make idempotent call - SetUnleasedStateAPM(leasedContainer); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId = leasedContainer.EndAcquireLease(result); - - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndAcquireLease(result); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndAcquireLease(result), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndAcquireLease(result), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndAcquireLease(result), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, leaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - - // Acquire with no proposed ID (non-idempotent) - SetUnleasedStateAPM(leasedContainer); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndAcquireLease(result); - result = leasedContainer.BeginAcquireLease(null /* infinite lease */, null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndAcquireLease(result), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - } - - // Delete the blob - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerAcquireLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Acquire the lease while in available state, make idempotent call - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - leaseId2 = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId), - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId), - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId).Wait(); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Wait(); - - // Acquire with no proposed ID (non-idempotent) - SetUnleasedState(leasedContainer); - leaseId = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */).Result; - TestHelper.ExpectedExceptionTask( - leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */), - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - this.DeleteAll(); - } -#endif - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseStateTests() - { - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Renew lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredState(leasedContainer); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = SetExpiredState(leasedContainer); - leasedContainer.FetchAttributes(); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = SetExpiredState(leasedContainer); - leasedContainer.SetMetadata(); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states in APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseStateTestsAPM() - { - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Renew lease in available state - SetUnleasedStateAPM(leasedContainer); - IAsyncResult result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredStateAPM(leasedContainer); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - - // Renew expired lease after read - leaseId = SetExpiredStateAPM(leasedContainer); - leasedContainer.FetchAttributes(); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - - // Renew expired lease after write - leaseId = SetExpiredStateAPM(leasedContainer); - leasedContainer.SetMetadata(); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - - // Renew finite lease - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(60)); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndRenewLease(result); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(60)); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedStateAPM(leasedContainer, TimeSpan.FromSeconds(60)); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedStateAPM(leasedContainer, TimeSpan.FromSeconds(60)); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndRenewLease(result), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - } - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerRenewLeaseStateTestsTask() - { - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Renew lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew infinite lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = SetExpiredState(leasedContainer); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after read - leaseId = SetExpiredState(leasedContainer); - leasedContainer.FetchAttributesAsync().Wait(); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew expired lease after write - leaseId = SetExpiredState(leasedContainer); - leasedContainer.SetMetadataAsync().Wait(); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew finite lease - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Renew finite lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = SetReleasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = SetReleasedState(leasedContainer, TimeSpan.FromSeconds(60)); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } -#endif - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerChangeLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Change lease in available state - SetUnleasedStateAPM(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2)), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states in APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerChangeLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Change lease in available state - SetUnleasedState(leasedContainer); - IAsyncResult result = leasedContainer.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndChangeLease(result); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndChangeLease(result); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndChangeLease(result); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndChangeLease(result); - - // Change lease (wrong lease specified) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseId2 = leasedContainer.EndChangeLease(result); - result = leasedContainer.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginChangeLease(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginChangeLease(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndChangeLease(result), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - } - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerChangeLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Change lease in available state - SetUnleasedStateAPM(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)).Result; - - // Change lease (wrong lease specified) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2)), - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } -#endif - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerReleaseLeaseStateTests() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Release lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = SetBreakingState(leasedContainer); - leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states in APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerReleaseLeaseStateTestsAPM() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Release lease in available state - SetUnleasedStateAPM(leasedContainer); - IAsyncResult result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndReleaseLease(result); - - // Release lease in released state (old lease) - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndReleaseLease(result); - - // Release breaking lease (wrong lease) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndReleaseLease(result); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(unknownLeaseId), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndReleaseLease(result), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - } - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerReleaseLeaseStateTestsTask() - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Release lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Release lease in released state (old lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)), - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = SetBreakingState(leasedContainer); - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Release breaking lease (wrong lease) - leaseId = SetBreakingState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId)), - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); - - // Release broken lease (wrong lease) - leaseId = SetInstantBrokenState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, new OperationContext()), - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - this.DeleteAll(); - } -#endif - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerBreakLeaseStateTests() - { - string leaseId; - TimeSpan leaseTime; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Break lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedException( - () => leasedContainer.BreakLease(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLease(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLease(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLease(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = SetBreakingState(leasedContainer); - leaseTime = leasedContainer.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingState(leasedContainer); - leasedContainer.BreakLease(null /* default break period */); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLease(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLease(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLease(null /* default break period */); - - // Break broken lease (default break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLease(null /* default break period */); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLease(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLease(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedException( - () => leasedContainer.BreakLease(null /* default break period */), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states in APM")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerBreakLeaseStateTestsAPM() - { - string leaseId; - TimeSpan leaseTime; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Break lease in available state - SetUnleasedStateAPM(leasedContainer); - IAsyncResult result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndBreakLease(result), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginBreakLease(TimeSpan.FromSeconds(1), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break breaking lease (zero break time) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingStateAPM(leasedContainer); - result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leasedContainer.EndBreakLease(result); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(50)); - result = leasedContainer.BeginBreakLease(TimeSpan.FromSeconds(60), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break finite lease (zero break time) - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(50)); - result = leasedContainer.BeginBreakLease(TimeSpan.Zero, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedStateAPM(leasedContainer, TimeSpan.FromSeconds(50)); - result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break broken lease (default break time) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginBreakLease(TimeSpan.FromSeconds(1), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenStateAPM(leasedContainer); - result = leasedContainer.BeginBreakLease(TimeSpan.Zero, null, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - leaseTime = leasedContainer.EndBreakLease(result); - - // Break released lease (default break time) - leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); - result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => leasedContainer.EndBreakLease(result), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - } - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerBreakLeaseStateTestsTask() - { - string leaseId; - TimeSpan leaseTime; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Break lease in available state - SetUnleasedState(leasedContainer); - TestHelper.ExpectedExceptionTask( - leasedContainer.BreakLeaseAsync(null /* default break period */), - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLeaseAsync(null /* default break period */).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)).Result; - - // Break infinite lease (60 seconds break time) - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Result; - - // Break breaking lease (zero break time) - leaseId = SetBreakingState(leasedContainer); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = SetBreakingState(leasedContainer); - leasedContainer.BreakLeaseAsync(null /* default break period */).Wait(); - - // Break finite lease (longer than lease time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)).Result; - - // Break finite lease (zero break time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLeaseAsync(TimeSpan.Zero).Result; - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = leasedContainer.BreakLeaseAsync(null /* default break period */).Result; - - // Break broken lease (default break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLeaseAsync(null /* default break period */).Wait(); - - // Break instant broken lease (nonzero break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)).Wait(); - - // Break instant broken lease (zero break time) - leaseId = SetInstantBrokenState(leasedContainer); - leasedContainer.BreakLeaseAsync(TimeSpan.Zero, null, null, null).Wait(); - - // Break released lease (default break time) - leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); - TestHelper.ExpectedExceptionTask( - leasedContainer.BreakLeaseAsync(null /* default break period */), - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - this.DeleteAll(); - } -#endif - [TestMethod] - [Description("Tests container delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedDeleteTests() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - - // Create the container - leasedContainer.Create(); - - // Verify that deletes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailure(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "delete container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = leasedContainer.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that deletes without a lease do not succeed. - testAccessCondition.LeaseId = null; - this.ContainerDeleteExpectLeaseFailure(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "delete container using no lease when a lease is held"); - - // Verify that deletes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailure(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "delete container using a lease when a different lease is held"); - - // Verify that deletes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerDeleteExpectLeaseSuccess(leasedContainer, testAccessCondition); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Tests container delete APIs in the presence of a lease usign APM.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedDeleteTestsAPM() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - - // Create the container - leasedContainer.Create(); - - // Verify that deletes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailureAPM(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "delete container using a lease when no lease is held"); - - // Acquire a lease - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = leasedContainer.BeginAcquireLease(null /* lease duration */, null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - string leaseId = leasedContainer.EndAcquireLease(result); - - // Verify that deletes without a lease do not succeed. - testAccessCondition.LeaseId = null; - this.ContainerDeleteExpectLeaseFailureAPM(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "delete container using no lease when a lease is held"); - - // Verify that deletes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailureAPM(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "delete container using a lease when a different lease is held"); - - // Verify that deletes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerDeleteExpectLeaseSuccessAPM(leasedContainer, testAccessCondition); - } - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Tests container delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedDeleteTestsTask() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - - // Create the container - leasedContainer.CreateAsync().Wait(); - - // Verify that deletes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailureTask(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "delete container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */).Result; - - // Verify that deletes without a lease do not succeed. - testAccessCondition.LeaseId = null; - this.ContainerDeleteExpectLeaseFailureTask(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "delete container using no lease when a lease is held"); - - // Verify that deletes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerDeleteExpectLeaseFailureTask(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "delete container using a lease when a different lease is held"); - - // Verify that deletes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerDeleteExpectLeaseSuccessTask(leasedContainer, testAccessCondition); - - this.DeleteAll(); - } -#endif - - /// - /// Test container deletion, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerDeleteExpectLeaseFailure(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedException( - () => testContainer.Delete(testAccessCondition, null /* options */), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container deletion, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerDeleteExpectLeaseFailureAPM(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testContainer.BeginDelete(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testContainer.EndDelete(result), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - } - -#if TASK - /// - /// Test container deletion, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerDeleteExpectLeaseFailureTask(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - TestHelper.ExpectedExceptionTask( - testContainer.DeleteAsync(testAccessCondition, null /* options */, null /* operationContext */), - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - -#endif - - /// - /// Test container deletion, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerDeleteExpectLeaseSuccess(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - testContainer.Delete(testAccessCondition, null /* options */); - } - - /// - /// Test container deletion, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerDeleteExpectLeaseSuccessAPM(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testContainer.BeginDelete(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testContainer.EndDelete(result); - } - } - -#if TASK - /// - /// Test container deletion, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerDeleteExpectLeaseSuccessTask(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - testContainer.DeleteAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); - } -#endif - - [TestMethod] - [Description("Tests container read and write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedReadWriteTests() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - leasedContainer.Create(); - - // Verify that reads and writes that pass a lease fail if none is present - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailure(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "read/write container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = leasedContainer.AcquireLease(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads and writes without a lease succeed. - testAccessCondition.LeaseId = null; - this.ContainerReadWriteExpectLeaseSuccess(leasedContainer, testAccessCondition); - - // Verify that reads and writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailure(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "read/write container using a lease when a different lease is held"); - - // Verify that reads and writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerReadWriteExpectLeaseSuccess(leasedContainer, testAccessCondition); - - this.DeleteAll(); - } - - [TestMethod] - [Description("Tests container read and write APIs in the presence of a lease using APM.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedReadWriteTestsAPM() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - leasedContainer.Create(); - - // Verify that reads and writes that pass a lease fail if none is present - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailureAPM(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "read/write container using a lease when no lease is held"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - - // Acquire a lease - IAsyncResult result = leasedContainer.BeginAcquireLease(null /* lease duration */, null /* proposed lease ID */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - string leaseId = leasedContainer.EndAcquireLease(result); - - // Verify that reads and writes without a lease succeed. - testAccessCondition.LeaseId = null; - this.ContainerReadWriteExpectLeaseSuccessAPM(leasedContainer, testAccessCondition); - - // Verify that reads and writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailureAPM(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "read/write container using a lease when a different lease is held"); - - // Verify that reads and writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerReadWriteExpectLeaseSuccessAPM(leasedContainer, testAccessCondition); - } - - this.DeleteAll(); - } - -#if TASK - [TestMethod] - [Description("Tests container read and write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeasedReadWriteTestsTask() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - leasedContainer.CreateAsync().Wait(); - - // Verify that reads and writes that pass a lease fail if none is present - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailureTask(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "read/write container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */).Result; - - // Verify that reads and writes without a lease succeed. - testAccessCondition.LeaseId = null; - this.ContainerReadWriteExpectLeaseSuccessTask(leasedContainer, testAccessCondition); - - // Verify that reads and writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - this.ContainerReadWriteExpectLeaseFailureTask(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "read/write container using a lease when a different lease is held"); - - // Verify that reads and writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - this.ContainerReadWriteExpectLeaseSuccessTask(leasedContainer, testAccessCondition); - - this.DeleteAll(); - } -#endif - /// - /// Test container reads and writes, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerReadWriteExpectLeaseFailure(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - TestHelper.ExpectedException( - () => testContainer.FetchAttributes(testAccessCondition, null /* options */), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - TestHelper.ExpectedException( - () => testContainer.GetPermissions(testAccessCondition, null /* options */), - description + " (Get Permissions)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testContainer.SetMetadata(testAccessCondition, null /* options */), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedException( - () => testContainer.SetPermissions(new BlobContainerPermissions(), testAccessCondition, null /* options */), - description + " (Set Permissions)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container reads and writes, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerReadWriteExpectLeaseFailureAPM(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testContainer.BeginFetchAttributes(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - TestHelper.ExpectedException( - () => testContainer.EndFetchAttributes(result), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - result = testContainer.BeginGetPermissions(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testContainer.EndGetPermissions(result), - description + " (Get Permissions)", - expectedStatusCode, - expectedErrorCode); - - result = testContainer.BeginSetMetadata(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testContainer.EndSetMetadata(result), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - - result = testContainer.BeginSetPermissions(new BlobContainerPermissions(), testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => testContainer.EndSetPermissions(result), - description + " (Set Permissions)", - expectedStatusCode, - expectedErrorCode); - } - } - -#if TASK - /// - /// Test container reads and writes, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private void ContainerReadWriteExpectLeaseFailureTask(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - TestHelper.ExpectedExceptionTask( - testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null /* operationContext */), - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - TestHelper.ExpectedExceptionTask( - testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null /* operationContext */), - description + " (Get Permissions)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedExceptionTask( - testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null /* operationContext */), - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - TestHelper.ExpectedExceptionTask( - testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null /* operationContext */), - description + " (Set Permissions)", - expectedStatusCode, - expectedErrorCode); - } -#endif - - /// - /// Test container reads and writes, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerReadWriteExpectLeaseSuccess(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - testContainer.FetchAttributes(testAccessCondition, null /* options */); - testContainer.GetPermissions(testAccessCondition, null /* options */); - testContainer.SetMetadata(testAccessCondition, null /* options */); - testContainer.SetPermissions(new BlobContainerPermissions(), testAccessCondition, null /* options */); - } - - /// - /// Test container reads and writes, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerReadWriteExpectLeaseSuccessAPM(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = testContainer.BeginFetchAttributes(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testContainer.EndFetchAttributes(result); - - result = testContainer.BeginGetPermissions(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testContainer.EndGetPermissions(result); - - result = testContainer.BeginSetMetadata(testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testContainer.EndSetMetadata(result); - - result = testContainer.BeginSetPermissions(new BlobContainerPermissions(), testAccessCondition, null /* options */, null /* operationContext */, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - testContainer.EndSetPermissions(result); - } - } - -#if TASK - /// - /// Test container reads and writes, expecting success. - /// - /// The container. - /// The access condition to use. - private void ContainerReadWriteExpectLeaseSuccessTask(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); - testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); - testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); - testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null /* operationContext */).Wait(); - } -#endif - - [TestMethod] - [Description("Test reading the container lease status after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ContainerLeaseStatusTest() - { - string leaseId; - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Check uninitialized lease status - SetUnleasedState(leasedContainer); - Assert.AreEqual(LeaseStatus.Unspecified, leasedContainer.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedContainer.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedContainer.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - SetUnleasedState(leasedContainer); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - SetLeasedState(leasedContainer, null /* infinite lease */); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - SetLeasedState(leasedContainer, TimeSpan.FromSeconds(45)); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - SetRenewedState(leasedContainer, null /* infinite lease */); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - SetRenewedState(leasedContainer, TimeSpan.FromSeconds(45)); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); - leasedContainer.ChangeLease(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = SetLeasedState(leasedContainer, TimeSpan.FromSeconds(45)); - leasedContainer.ChangeLease(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - SetReleasedState(leasedContainer, null /* infinite lease */); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - SetBreakingState(leasedContainer); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - SetTimeBrokenState(leasedContainer); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - SetTimeBrokenState(leasedContainer); - leasedContainer.AcquireLease(null /* infinite lease */, null /*proposed lease ID */); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - SetInstantBrokenState(leasedContainer); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - SetExpiredState(leasedContainer); - this.CheckLeaseStatus(leasedContainer, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - this.DeleteAll(); - } - - /// - /// Checks the lease status of a container, both from its attributes and from a container listing. - /// - /// The container to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private void CheckLeaseStatus( - CloudBlobContainer container, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - container.FetchAttributes(); - Assert.AreEqual(expectedStatus, container.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, container.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, container.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - BlobContainerProperties propertiesInListing = (from CloudBlobContainer c in this.blobClient.ListContainers( - container.Name, - ContainerListingDetails.None) - where c.Name == container.Name - select c.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListContainers)"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/MD5FlagsTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/MD5FlagsTest.cs deleted file mode 100644 index cc67d4891c43e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/MD5FlagsTest.cs +++ /dev/null @@ -1,1119 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Security.Cryptography; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class MD5FlagsTest : BlobTestBase - { - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Test StoreBlobContentMD5 flag with UploadFromStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StoreBlobContentMD5Test() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - ICloudBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithMD5); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob2"); - using (Stream stream = new NonSeekableMemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithNoMD5); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob3"); - using (Stream stream = new NonSeekableMemoryStream()) - { - blob.UploadFromStream(stream); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob4"); - using (Stream stream = new MemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithMD5); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob5"); - using (Stream stream = new MemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithNoMD5); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob6"); - using (Stream stream = new MemoryStream()) - { - blob.UploadFromStream(stream); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test StoreBlobContentMD5 flag with UploadFromStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StoreBlobContentMD5TestAPM() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - ICloudBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream()) - { - result = blob.BeginUploadFromStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob2"); - using (Stream stream = new NonSeekableMemoryStream()) - { - result = blob.BeginUploadFromStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob3"); - using (Stream stream = new NonSeekableMemoryStream()) - { - result = blob.BeginUploadFromStream(stream, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob4"); - using (Stream stream = new MemoryStream()) - { - result = blob.BeginUploadFromStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob5"); - using (Stream stream = new MemoryStream()) - { - result = blob.BeginUploadFromStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob6"); - using (Stream stream = new MemoryStream()) - { - result = blob.BeginUploadFromStream(stream, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndUploadFromStream(result); - } - blob.FetchAttributes(); - Assert.IsNull(blob.Properties.ContentMD5); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test DisableContentMD5Validation flag with DownloadToStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void DisableContentMD5ValidationTest() - { - byte[] buffer = new byte[1024]; - Random random = new Random(); - random.NextBytes(buffer); - - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - StoreBlobContentMD5 = true, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = false, - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream(buffer)) - { - blockBlob.UploadFromStream(stream, null, optionsWithMD5); - } - - using (Stream stream = new MemoryStream()) - { - blockBlob.DownloadToStream(stream, null, optionsWithMD5); - blockBlob.DownloadToStream(stream, null, optionsWithNoMD5); - - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithNoMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - - blockBlob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blockBlob.SetProperties(); - - TestHelper.ExpectedException( - () => blockBlob.DownloadToStream(stream, null, optionsWithMD5), - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - blockBlob.DownloadToStream(stream, null, optionsWithNoMD5); - - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithMD5)) - { - TestHelper.ExpectedException( - () => - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - }, - "Downloading a blob with invalid MD5 should fail"); - } - - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithNoMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - } - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - using (Stream stream = new MemoryStream(buffer)) - { - pageBlob.UploadFromStream(stream, null, optionsWithMD5); - } - - using (Stream stream = new MemoryStream()) - { - pageBlob.DownloadToStream(stream, null, optionsWithMD5); - pageBlob.DownloadToStream(stream, null, optionsWithNoMD5); - - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithNoMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - - pageBlob.Properties.ContentMD5 = "MDAwMDAwMDA="; - pageBlob.SetProperties(); - - TestHelper.ExpectedException( - () => pageBlob.DownloadToStream(stream, null, optionsWithMD5), - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - pageBlob.DownloadToStream(stream, null, optionsWithNoMD5); - - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithMD5)) - { - TestHelper.ExpectedException( - () => - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - }, - "Downloading a blob with invalid MD5 should fail"); - } - - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithNoMD5)) - { - int read; - do - { - read = blobStream.Read(buffer, 0, buffer.Length); - } - while (read > 0); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test DisableContentMD5Validation flag with DownloadToStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void DisableContentMD5ValidationTestAPM() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - StoreBlobContentMD5 = true, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = false, - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - ICloudBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithMD5); - } - - using (Stream stream = new MemoryStream()) - { - result = blob.BeginDownloadToStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - result = blob.BeginDownloadToStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.SetProperties(); - - result = blob.BeginDownloadToStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndDownloadToStream(result), - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - result = blob.BeginDownloadToStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - } - - blob = container.GetPageBlobReference("blob2"); - using (Stream stream = new MemoryStream()) - { - blob.UploadFromStream(stream, null, optionsWithMD5); - } - - using (Stream stream = new MemoryStream()) - { - result = blob.BeginDownloadToStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - result = blob.BeginDownloadToStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.SetProperties(); - - result = blob.BeginDownloadToStream(stream, null, optionsWithMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => blob.EndDownloadToStream(result), - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - result = blob.BeginDownloadToStream(stream, null, optionsWithNoMD5, null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blob.EndDownloadToStream(result); - } - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test UseTransactionalMD5 flag with PutBlock and WritePages")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void UseTransactionalMD5PutTest() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - }; - - byte[] buffer = GetRandomBuffer(1024); - MD5 hasher = MD5.Create(); - string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); - - string lastCheckMD5 = null; - int checkCount = 0; - OperationContext opContextWithMD5Check = new OperationContext(); - opContextWithMD5Check.SendingRequest += (_, args) => - { - if (args.Request.ContentLength >= buffer.Length) - { - lastCheckMD5 = args.Request.Headers[HttpRequestHeader.ContentMd5]; - checkCount++; - } - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - List blockIds = GetBlockIdList(3); - checkCount = 0; - using (Stream blockData = new MemoryStream(buffer)) - { - lastCheckMD5 = "invalid_md5"; - blockBlob.PutBlock(blockIds[0], blockData, null, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockData.Seek(0, SeekOrigin.Begin); - blockBlob.PutBlock(blockIds[1], blockData, null, null, optionsWithMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockData.Seek(0, SeekOrigin.Begin); - blockBlob.PutBlock(blockIds[2], blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - } - - Assert.AreEqual(3, checkCount); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - pageBlob.Create(buffer.Length); - checkCount = 0; - using (Stream pageData = new MemoryStream(buffer)) - { - lastCheckMD5 = "invalid_md5"; - pageBlob.WritePages(pageData, 0, null, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageData.Seek(0, SeekOrigin.Begin); - pageBlob.WritePages(pageData, 0, null, null, optionsWithMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageData.Seek(0, SeekOrigin.Begin); - pageBlob.WritePages(pageData, 0, md5, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - } - - Assert.AreEqual(3, checkCount); - - lastCheckMD5 = null; - blockBlob = container.GetBlockBlobReference("blob3"); - checkCount = 0; - using (Stream blobStream = blockBlob.OpenWrite(null, optionsWithMD5, opContextWithMD5Check)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - Assert.IsNotNull(lastCheckMD5); - Assert.AreEqual(1, checkCount); - - lastCheckMD5 = "invalid_md5"; - blockBlob = container.GetBlockBlobReference("blob4"); - checkCount = 0; - using (Stream blobStream = blockBlob.OpenWrite(null, optionsWithNoMD5, opContextWithMD5Check)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - Assert.IsNull(lastCheckMD5); - Assert.AreEqual(1, checkCount); - - lastCheckMD5 = null; - pageBlob = container.GetPageBlobReference("blob5"); - checkCount = 0; - using (Stream blobStream = pageBlob.OpenWrite(buffer.Length * 3, null, optionsWithMD5, opContextWithMD5Check)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - Assert.IsNotNull(lastCheckMD5); - Assert.AreEqual(1, checkCount); - - lastCheckMD5 = "invalid_md5"; - pageBlob = container.GetPageBlobReference("blob6"); - checkCount = 0; - using (Stream blobStream = pageBlob.OpenWrite(buffer.Length * 3, null, optionsWithNoMD5, opContextWithMD5Check)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - Assert.IsNull(lastCheckMD5); - Assert.AreEqual(1, checkCount); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test UseTransactionalMD5 flag with PutBlock and WritePages")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void UseTransactionalMD5PutTestAPM() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - }; - - byte[] buffer = GetRandomBuffer(1024); - MD5 hasher = MD5.Create(); - string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); - - string lastCheckMD5 = null; - int checkCount = 0; - OperationContext opContextWithMD5Check = new OperationContext(); - opContextWithMD5Check.SendingRequest += (_, args) => - { - if (args.Request.ContentLength >= buffer.Length) - { - lastCheckMD5 = args.Request.Headers[HttpRequestHeader.ContentMd5]; - checkCount++; - } - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - List blockIds = GetBlockIdList(3); - checkCount = 0; - using (Stream blockData = new MemoryStream(buffer)) - { - lastCheckMD5 = "invalid_md5"; - result = blockBlob.BeginPutBlock(blockIds[0], blockData, null, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndPutBlock(result); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockData.Seek(0, SeekOrigin.Begin); - result = blockBlob.BeginPutBlock(blockIds[1], blockData, null, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndPutBlock(result); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockData.Seek(0, SeekOrigin.Begin); - result = blockBlob.BeginPutBlock(blockIds[2], blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndPutBlock(result); - Assert.AreEqual(md5, lastCheckMD5); - } - - Assert.AreEqual(3, checkCount); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - pageBlob.Create(buffer.Length); - checkCount = 0; - using (Stream pageData = new MemoryStream(buffer)) - { - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginWritePages(pageData, 0, null, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndWritePages(result); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageData.Seek(0, SeekOrigin.Begin); - result = pageBlob.BeginWritePages(pageData, 0, null, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndWritePages(result); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageData.Seek(0, SeekOrigin.Begin); - result = pageBlob.BeginWritePages(pageData, 0, md5, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndWritePages(result); - Assert.AreEqual(md5, lastCheckMD5); - } - - Assert.AreEqual(3, checkCount); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test UseTransactionalMD5 flag with DownloadRangeToStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void UseTransactionalMD5GetTest() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - }; - - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - MD5 hasher = MD5.Create(); - string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); - - string lastCheckMD5 = null; - int checkCount = 0; - OperationContext opContextWithMD5Check = new OperationContext(); - opContextWithMD5Check.ResponseReceived += (_, args) => - { - if (args.Response.ContentLength >= buffer.Length) - { - lastCheckMD5 = args.Response.Headers[HttpResponseHeader.ContentMd5]; - checkCount++; - } - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream blobStream = blockBlob.OpenWrite()) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - - checkCount = 0; - using (Stream stream = new MemoryStream()) - { - lastCheckMD5 = null; - blockBlob.DownloadToStream(stream, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNotNull(lastCheckMD5); - - lastCheckMD5 = null; - blockBlob.DownloadToStream(stream, null, optionsWithMD5, opContextWithMD5Check); - Assert.IsNotNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockBlob.DownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockBlob.DownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - blockBlob.DownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - StorageException storageEx = TestHelper.ExpectedException( - () => blockBlob.DownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check), - "Downloading more than 4MB with transactional MD5 should not be supported"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - - lastCheckMD5 = null; - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithMD5, opContextWithMD5Check)) - { - blobStream.CopyTo(stream); - Assert.IsNotNull(lastCheckMD5); - } - - lastCheckMD5 = "invalid_md5"; - using (Stream blobStream = blockBlob.OpenRead(null, optionsWithNoMD5, opContextWithMD5Check)) - { - blobStream.CopyTo(stream); - Assert.IsNull(lastCheckMD5); - } - } - - Assert.AreEqual(9, checkCount); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - using (Stream blobStream = pageBlob.OpenWrite(buffer.Length * 2)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - - checkCount = 0; - using (Stream stream = new MemoryStream()) - { - lastCheckMD5 = "invalid_md5"; - pageBlob.DownloadToStream(stream, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - StorageException storageEx = TestHelper.ExpectedException( - () => pageBlob.DownloadToStream(stream, null, optionsWithMD5, opContextWithMD5Check), - "Page blob will not have MD5 set by default; with UseTransactional, download should fail"); - - lastCheckMD5 = "invalid_md5"; - pageBlob.DownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageBlob.DownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - pageBlob.DownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); - Assert.IsNull(lastCheckMD5); - - storageEx = TestHelper.ExpectedException( - () => pageBlob.DownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check), - "Downloading more than 4MB with transactional MD5 should not be supported"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - - lastCheckMD5 = null; - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithMD5, opContextWithMD5Check)) - { - blobStream.CopyTo(stream); - Assert.IsNotNull(lastCheckMD5); - } - - lastCheckMD5 = "invalid_md5"; - using (Stream blobStream = pageBlob.OpenRead(null, optionsWithNoMD5, opContextWithMD5Check)) - { - blobStream.CopyTo(stream); - Assert.IsNull(lastCheckMD5); - } - } - - Assert.AreEqual(9, checkCount); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test UseTransactionalMD5 flag with DownloadRangeToStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void UseTransactionalMD5GetTestAPM() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - }; - - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - MD5 hasher = MD5.Create(); - string md5 = Convert.ToBase64String(hasher.ComputeHash(buffer)); - - string lastCheckMD5 = null; - int checkCount = 0; - OperationContext opContextWithMD5Check = new OperationContext(); - opContextWithMD5Check.ResponseReceived += (_, args) => - { - if (args.Response.ContentLength >= buffer.Length) - { - lastCheckMD5 = args.Response.Headers[HttpResponseHeader.ContentMd5]; - checkCount++; - } - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream blobStream = blockBlob.OpenWrite()) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - - checkCount = 0; - using (Stream stream = new MemoryStream()) - { - lastCheckMD5 = null; - result = blockBlob.BeginDownloadToStream(stream, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndDownloadRangeToStream(result); - Assert.IsNotNull(lastCheckMD5); - - lastCheckMD5 = null; - result = blockBlob.BeginDownloadToStream(stream, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndDownloadRangeToStream(result); - Assert.IsNotNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - result = blockBlob.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndDownloadRangeToStream(result); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - result = blockBlob.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndDownloadRangeToStream(result); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - result = blockBlob.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - blockBlob.EndDownloadRangeToStream(result); - Assert.IsNull(lastCheckMD5); - - result = blockBlob.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - StorageException storageEx = TestHelper.ExpectedException( - () => blockBlob.EndDownloadRangeToStream(result), - "Downloading more than 4MB with transactional MD5 should not be supported"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - - lastCheckMD5 = null; - result = blockBlob.BeginOpenRead(null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blockBlob.EndOpenRead(result)) - { - blobStream.CopyTo(stream); - Assert.IsNotNull(lastCheckMD5); - } - - lastCheckMD5 = "invalid_md5"; - result = blockBlob.BeginOpenRead(null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = blockBlob.EndOpenRead(result)) - { - blobStream.CopyTo(stream); - Assert.IsNull(lastCheckMD5); - } - } - - Assert.AreEqual(9, checkCount); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - using (Stream blobStream = pageBlob.OpenWrite(buffer.Length * 2)) - { - blobStream.Write(buffer, 0, buffer.Length); - blobStream.Write(buffer, 0, buffer.Length); - } - - checkCount = 0; - using (Stream stream = new MemoryStream()) - { - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginDownloadToStream(stream, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndDownloadRangeToStream(result); - Assert.IsNull(lastCheckMD5); - - result = pageBlob.BeginDownloadToStream(stream, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - StorageException storageEx = TestHelper.ExpectedException( - () => pageBlob.EndDownloadRangeToStream(result), - "Page blob will not have MD5 set by default; with UseTransactional, download should fail"); - - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndDownloadRangeToStream(result); - Assert.IsNull(lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginDownloadRangeToStream(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndDownloadRangeToStream(result); - Assert.AreEqual(md5, lastCheckMD5); - - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - pageBlob.EndDownloadRangeToStream(result); - Assert.IsNull(lastCheckMD5); - - result = pageBlob.BeginDownloadRangeToStream(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - storageEx = TestHelper.ExpectedException( - () => pageBlob.EndDownloadRangeToStream(result), - "Downloading more than 4MB with transactional MD5 should not be supported"); - Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); - - lastCheckMD5 = null; - result = pageBlob.BeginOpenRead(null, optionsWithMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = pageBlob.EndOpenRead(result)) - { - blobStream.CopyTo(stream); - Assert.IsNotNull(lastCheckMD5); - } - - lastCheckMD5 = "invalid_md5"; - result = pageBlob.BeginOpenRead(null, optionsWithNoMD5, opContextWithMD5Check, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - using (Stream blobStream = pageBlob.EndOpenRead(result)) - { - blobStream.CopyTo(stream); - Assert.IsNull(lastCheckMD5); - } - } - - Assert.AreEqual(9, checkCount); - } - } - finally - { - container.DeleteIfExists(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobClientTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobClientTests.cs deleted file mode 100644 index 6fbaf426700bf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobClientTests.cs +++ /dev/null @@ -1,1017 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - internal class BlobClientTests - { - public BlobContext BlobContext { get; private set; } - - public BlobProperties Properties { get; private set; } - public string LeaseId { get; private set; } - public string BlobName { get; private set; } - public string ContainerName { get; private set; } - public string PublicBlobName { get; private set; } - public string PublicContainerName { get; private set; } - public byte[] Content { get; private set; } - - private Random random = new Random(); - - public BlobClientTests(bool owner, bool isAsync, int timeout) - { - BlobContext = new BlobContext(owner, isAsync, timeout); - } - - public void Initialize() - { - ContainerName = "defaultcontainer"; - PublicContainerName = "publiccontainer"; - BlobName = "defaultblob"; - PublicBlobName = "public"; - - Content = new byte[7000]; - random.NextBytes(Content); - - CreateContainer(ContainerName, false); - CreateBlob(ContainerName, BlobName, false); - CreateContainer(PublicContainerName, true); - CreateBlob(PublicContainerName, PublicBlobName, true); - } - - public void Cleanup() - { - DeleteContainer(ContainerName); - DeleteContainer(PublicContainerName); - } - - public void CreateContainer(string containerName, bool isPublic) - { - CreateContainer(containerName, isPublic, 3); - } - - public void CreateContainer(string containerName, bool isPublic, int retries) - { - // by default, sleep 35 seconds between retries - CreateContainer(containerName, isPublic, retries, 35000); - } - - public void CreateContainer(string containerName, bool isPublic, int retries, int millisecondsBetweenRetries) - { - while (true) - { - HttpWebRequest request = BlobTests.CreateContainerRequest(BlobContext, containerName); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (isPublic) - { - request.Headers["x-ms-blob-public-access"] = "container"; - } - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - HttpStatusCode statusCode = response.StatusCode; - string statusDescription = response.StatusDescription; - StorageExtendedErrorInformation error = StorageExtendedErrorInformation.ReadFromStream(response.GetResponseStream()); - response.Close(); - - // if the container is being deleted, retry up to the specified times. - if (statusCode == HttpStatusCode.Conflict && error != null && error.ErrorCode == BlobErrorCodeStrings.ContainerBeingDeleted && retries > 0) - { - Thread.Sleep(millisecondsBetweenRetries); - retries--; - continue; - } - - break; - } - } - - public void DeleteContainer(string containerName) - { - HttpWebRequest request = BlobTests.DeleteContainerRequest(BlobContext, containerName, null); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - HttpStatusCode statusCode = response.StatusCode; - string statusDescription = response.StatusDescription; - response.Close(); - } - - public void CreateBlob(string containerName, string blobName, bool isPublic) - { - Properties = new BlobProperties() { BlobType = BlobType.BlockBlob }; - HttpWebRequest request = BlobTests.PutBlobRequest(BlobContext, containerName, blobName, Properties, BlobType.BlockBlob, Content, 0, null); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - - request.ContentLength = Content.Length; - request.Timeout = 30000; - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - Stream stream = request.GetRequestStream(); - stream.Write(Content, 0, Content.Length); - stream.Flush(); - stream.Close(); - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - HttpStatusCode statusCode = response.StatusCode; - string statusDescription = response.StatusDescription; - response.Close(); - if (statusCode != HttpStatusCode.Created) - { - Assert.Fail(string.Format("Failed to create blob: {0}, Status: {1}, Status Description: {2}", containerName, statusCode, statusDescription)); - } - } - - public void DeleteBlob(string containerName, string blobName) - { - HttpWebRequest request = BlobTests.DeleteBlobRequest(BlobContext, containerName, blobName, null); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - response.Close(); - } - - /// - /// Scenario test for acquiring a lease. - /// - /// The name of the container. - /// The name of the blob, if any. - /// The lease duration. - /// The proposed lease ID. - /// The error status code to expect. - /// The lease ID. - public string AcquireLeaseScenarioTest(string containerName, string blobName, int leaseDuration, string proposedLeaseId, HttpStatusCode? expectedError) - { - // Create and validate the web request - HttpWebRequest request = BlobTests.AcquireLeaseRequest(BlobContext, containerName, blobName, leaseDuration, proposedLeaseId, null); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext)) - { - BlobTests.AcquireLeaseResponse(response, proposedLeaseId, expectedError); - - return BlobHttpResponseParsers.GetLeaseId(response); - } - } - - /// - /// Scenario test for renewing a lease. - /// - /// The name of the container. - /// The name of the blob, if any. - /// The lease ID. - /// The error status code to expect. - public void RenewLeaseScenarioTest(string containerName, string blobName, string leaseId, HttpStatusCode? expectedError) - { - // Create and validate the web request - HttpWebRequest request = BlobTests.RenewLeaseRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId)); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext)) - { - BlobTests.RenewLeaseResponse(response, leaseId, expectedError); - } - } - - /// - /// Scenario test for changing a lease. - /// - /// The name of the container. - /// The name of the blob, if any. - /// The lease ID. - /// The proposed lease ID. - /// The error status code to expect. - /// The lease ID. - public string ChangeLeaseScenarioTest(string containerName, string blobName, string leaseId, string proposedLeaseId, HttpStatusCode? expectedError) - { - // Create and validate the web request - HttpWebRequest request = BlobTests.ChangeLeaseRequest(BlobContext, containerName, blobName, proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId)); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext)) - { - BlobTests.ChangeLeaseResponse(response, proposedLeaseId, expectedError); - - return BlobHttpResponseParsers.GetLeaseId(response); - } - } - - /// - /// Scenario test for releasing a lease. - /// - /// The name of the container. - /// The name of the blob, if any. - /// The lease ID. - /// The error status code to expect. - public void ReleaseLeaseScenarioTest(string containerName, string blobName, string leaseId, HttpStatusCode? expectedError) - { - // Create and validate the web request - HttpWebRequest request = BlobTests.ReleaseLeaseRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId)); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext)) - { - BlobTests.ReleaseLeaseResponse(response, expectedError); - } - } - - /// - /// Scenario test for breaking a lease. - /// - /// The name of the container. - /// The name of the blob, if any. - /// The break period. - /// The expected remaining time. - /// The error status code to expect. - /// The remaining lease time. - public int BreakLeaseScenarioTest(string containerName, string blobName, int? breakPeriod, int? expectedRemainingTime, HttpStatusCode? expectedError) - { - // Create and validate the web request - HttpWebRequest request = BlobTests.BreakLeaseRequest(BlobContext, containerName, blobName, breakPeriod, null); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext)) - { - int expectedTime = expectedRemainingTime ?? breakPeriod.Value; - int errorMargin = 10; - BlobTests.BreakLeaseResponse(response, expectedTime, errorMargin, expectedError); - - return expectedError.HasValue ? 0 : BlobHttpResponseParsers.GetRemainingLeaseTime(response).Value; - } - } - - /// - /// Test acquire lease semantics. - /// - /// The container. - /// The blob, if any. - public void AcquireLeaseTests(string containerName, string blobName) - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - // Acquire the lease while in available state - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Acquire the lease while in leased state (idempotent) - leaseId2 = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Acquire the lease while in leased state (conflict) - AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId2, HttpStatusCode.Conflict); - - // Break lease for 60 seconds - BreakLeaseScenarioTest(containerName, blobName, 60, 60, null); - - // Acquire the lease while in breaking state (conflict) - AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, HttpStatusCode.Conflict); - AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId2, HttpStatusCode.Conflict); - - // Break lease instantly - BreakLeaseScenarioTest(containerName, blobName, 0, 0, null); - - // Acquire the lease while in broken state (same ID) - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease instantly - BreakLeaseScenarioTest(containerName, blobName, 0, 0, null); - - // Acquire the lease while in broken state (new ID) - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId2, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire the lease while in released state (same ID) - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId2, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire the lease while in released state (new ID) - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire a lease that is too short - AcquireLeaseScenarioTest(containerName, blobName, 14, proposedLeaseId, HttpStatusCode.BadRequest); - - // Acquire a lease that is too long - AcquireLeaseScenarioTest(containerName, blobName, 61, proposedLeaseId, HttpStatusCode.BadRequest); - - // Acquire minimum finite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, 15, proposedLeaseId, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire maximum finite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, 60, proposedLeaseId, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire with no proposed ID (non-idempotent) - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, null, null); - - // Acquire with no proposed ID (attempt to use as though idempotent) - AcquireLeaseScenarioTest(containerName, blobName, -1, null, HttpStatusCode.Conflict); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - } - - /// - /// Test renew lease semantics. - /// - /// The container. - /// The blob, if any. - public void RenewLeaseTests(string containerName, string blobName) - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - // Renew lease (no lease) - RenewLeaseScenarioTest(containerName, blobName, null, HttpStatusCode.BadRequest); - - // Renew lease in available state - RenewLeaseScenarioTest(containerName, blobName, proposedLeaseId, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Renew infinite lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Renew released lease (wrong lease) - RenewLeaseScenarioTest(containerName, blobName, unknownLeaseId, HttpStatusCode.Conflict); - - // Renew released infinite lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, HttpStatusCode.Conflict); - - // Acquire finite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, 60, proposedLeaseId, null); - - // Renew finite lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Renew lease (wrong lease) - RenewLeaseScenarioTest(containerName, blobName, unknownLeaseId, HttpStatusCode.Conflict); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Renew released finite lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease for 60 seconds - BreakLeaseScenarioTest(containerName, blobName, 60, 60, null); - - // Renew breaking lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, HttpStatusCode.Conflict); - - // Break lease instantly - BreakLeaseScenarioTest(containerName, blobName, 0, 0, null); - - // Renew broken lease - RenewLeaseScenarioTest(containerName, blobName, leaseId, HttpStatusCode.Conflict); - } - - /// - /// Test change lease semantics. - /// - /// The container. - /// The blob, if any. - public void ChangeLeaseTests(string containerName, string blobName) - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - // Change lease (no lease) - ChangeLeaseScenarioTest(containerName, blobName, null, proposedLeaseId2, HttpStatusCode.BadRequest); - - // Change lease (no proposed lease) - ChangeLeaseScenarioTest(containerName, blobName, proposedLeaseId, null, HttpStatusCode.BadRequest); - - // Change lease in available state - ChangeLeaseScenarioTest(containerName, blobName, proposedLeaseId, proposedLeaseId2, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Change lease - leaseId2 = ChangeLeaseScenarioTest(containerName, blobName, leaseId, proposedLeaseId2, null); - - // Change lease (idempotent) - leaseId2 = ChangeLeaseScenarioTest(containerName, blobName, leaseId, proposedLeaseId2, null); - - // Change lease (idempotent, other source) - leaseId2 = ChangeLeaseScenarioTest(containerName, blobName, unknownLeaseId, proposedLeaseId2, null); - - // Change lease (wrong lease) - ChangeLeaseScenarioTest(containerName, blobName, unknownLeaseId, proposedLeaseId, HttpStatusCode.Conflict); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId2, null); - - // Change released lease - ChangeLeaseScenarioTest(containerName, blobName, leaseId2, proposedLeaseId, HttpStatusCode.Conflict); - - // Change released lease (idempotent attempt) - ChangeLeaseScenarioTest(containerName, blobName, leaseId, proposedLeaseId2, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease for 60 seconds - BreakLeaseScenarioTest(containerName, blobName, 60, 60, null); - - // Change breaking lease - ChangeLeaseScenarioTest(containerName, blobName, leaseId, proposedLeaseId2, HttpStatusCode.Conflict); - - // Change breaking lease (idempotent attempt) - ChangeLeaseScenarioTest(containerName, blobName, leaseId2, proposedLeaseId, HttpStatusCode.Conflict); - - // Break lease instantly - BreakLeaseScenarioTest(containerName, blobName, 0, 0, null); - - // Change broken lease - ChangeLeaseScenarioTest(containerName, blobName, leaseId, proposedLeaseId2, HttpStatusCode.Conflict); - - // Change broken lease (idempotent attempt) - ChangeLeaseScenarioTest(containerName, blobName, leaseId2, proposedLeaseId, HttpStatusCode.Conflict); - } - - /// - /// Test release lease semantics. - /// - /// The container. - /// The blob, if any. - public void ReleaseLeaseTests(string containerName, string blobName) - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - // Release lease (no lease) - ReleaseLeaseScenarioTest(containerName, blobName, null, HttpStatusCode.BadRequest); - - // Release lease in available state (unknown lease) - ReleaseLeaseScenarioTest(containerName, blobName, proposedLeaseId, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Release lease (wrong lease) - ReleaseLeaseScenarioTest(containerName, blobName, unknownLeaseId, HttpStatusCode.Conflict); - - // Release lease (right lease) - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Release lease (old lease) - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, HttpStatusCode.Conflict); - - // Release lease in released state (unknown lease) - ReleaseLeaseScenarioTest(containerName, blobName, unknownLeaseId, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease for 60 seconds - BreakLeaseScenarioTest(containerName, blobName, 60, 60, null); - - // Release breaking lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease instantly - BreakLeaseScenarioTest(containerName, blobName, 0, 0, null); - - // Release broken lease (right lease) - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Release broken lease (wrong lease) - ReleaseLeaseScenarioTest(containerName, blobName, unknownLeaseId, HttpStatusCode.Conflict); - } - - /// - /// Test break lease semantics. - /// - /// The container. - /// The blob, if any. - public void BreakLeaseTests(string containerName, string blobName) - { - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - int leaseTime; - - // Break lease in available state - BreakLeaseScenarioTest(containerName, blobName, null, 0, HttpStatusCode.Conflict); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease (negative break time) - BreakLeaseScenarioTest(containerName, blobName, -1, null, HttpStatusCode.BadRequest); - - // Break lease (too large break time) - BreakLeaseScenarioTest(containerName, blobName, 61, null, HttpStatusCode.BadRequest); - - // Break lease (default break time) - BreakLeaseScenarioTest(containerName, blobName, null, 0, null); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease (zero break time) - BreakLeaseScenarioTest(containerName, blobName, 0, null, null); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease (1 second break time) - BreakLeaseScenarioTest(containerName, blobName, 1, null, null); - - // Wait for lease to break - Thread.Sleep(TimeSpan.FromSeconds(2)); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Break lease (60 seconds break time) - BreakLeaseScenarioTest(containerName, blobName, 60, null, null); - - // Break breaking lease (zero break time) - BreakLeaseScenarioTest(containerName, blobName, 0, null, null); - - // Acquire finite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, 59, proposedLeaseId, null); - - // Break lease (longer than lease time) - BreakLeaseScenarioTest(containerName, blobName, 60, 59, null); - - // Break lease (zero break time) - BreakLeaseScenarioTest(containerName, blobName, 0, null, null); - - // Acquire finite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, 60, proposedLeaseId, null); - - // Break lease (default break time) - leaseTime = BreakLeaseScenarioTest(containerName, blobName, null, 60, null); - - // Break breaking lease (default break time) - BreakLeaseScenarioTest(containerName, blobName, null, leaseTime, null); - - // Break breaking lease (zero break time) - BreakLeaseScenarioTest(containerName, blobName, 0, null, null); - - // Acquire infinite lease - leaseId = AcquireLeaseScenarioTest(containerName, blobName, -1, proposedLeaseId, null); - - // Release lease - ReleaseLeaseScenarioTest(containerName, blobName, leaseId, null); - - // Break released lease - BreakLeaseScenarioTest(containerName, blobName, null, 0, HttpStatusCode.Conflict); - } - - public void PutBlobScenarioTest(string containerName, string blobName, BlobProperties properties, BlobType blobType, byte[] content, HttpStatusCode? expectedError) - { - HttpWebRequest request = BlobTests.PutBlobRequest(BlobContext, containerName, blobName, properties, blobType, content, content.Length, null); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - request.ContentLength = content.Length; - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - BlobTestUtils.SetRequest(request, BlobContext, content); - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.PutBlobResponse(response, BlobContext, expectedError); - } - finally - { - response.Close(); - } - } - - public void ClearPageRangeScenarioTest(string containerName, string blobName, HttpStatusCode? expectedError) - { - // 1. Create Sparse Page Blob - int blobSize = 128 * 1024; - - BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; - Uri uri = BlobTests.ConstructPutUri(BlobContext.Address, containerName, blobName); - OperationContext opContext = new OperationContext(); - HttpWebRequest webRequest = BlobHttpWebRequestFactory.Put(uri, BlobContext.Timeout, properties, BlobType.PageBlob, blobSize, null, opContext); - - BlobTests.SignRequest(webRequest, BlobContext); - - using (HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse) - { - BlobTests.PutBlobResponse(response, BlobContext, expectedError); - } - - // 2. Now upload some page ranges - for (int m = 0; m * 512 * 4 < blobSize; m++) - { - int startOffset = 512 * 4 * m; - int length = 512; - - PageRange range = new PageRange(startOffset, startOffset + length - 1); - opContext = new OperationContext(); - HttpWebRequest pageRequest = BlobHttpWebRequestFactory.PutPage(uri, BlobContext.Timeout, range, PageWrite.Update, null, opContext); - pageRequest.ContentLength = 512; - BlobTests.SignRequest(pageRequest, BlobContext); - - Stream outStream = pageRequest.GetRequestStream(); - - for (int n = 0; n < 512; n++) - { - outStream.WriteByte((byte)m); - } - - outStream.Close(); - using (HttpWebResponse pageResponse = pageRequest.GetResponse() as HttpWebResponse) - { - } - } - - // 3. Now do a Get Page Ranges - List pageRanges = new List(); - opContext = new OperationContext(); - HttpWebRequest pageRangeRequest = BlobHttpWebRequestFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, opContext); - BlobTests.SignRequest(pageRangeRequest, BlobContext); - using (HttpWebResponse pageRangeResponse = pageRangeRequest.GetResponse() as HttpWebResponse) - { - GetPageRangesResponse getPageRangesResponse = new GetPageRangesResponse(pageRangeResponse.GetResponseStream()); - pageRanges.AddRange(getPageRangesResponse.PageRanges.ToList()); - } - - // 4. Now Clear some pages - bool skipFlag = false; - foreach (PageRange pRange in pageRanges) - { - skipFlag = !skipFlag; - if (skipFlag) - { - continue; - } - - opContext = new OperationContext(); - HttpWebRequest clearPageRequest = BlobHttpWebRequestFactory.PutPage(uri, BlobContext.Timeout, pRange, PageWrite.Clear, null, opContext); - clearPageRequest.ContentLength = 0; - BlobTests.SignRequest(clearPageRequest, BlobContext); - using (HttpWebResponse clearResponse = clearPageRequest.GetResponse() as HttpWebResponse) - { - } - } - - // 5. Get New Page ranges and verify - List newPageRanges = new List(); - - opContext = new OperationContext(); - HttpWebRequest newPageRangeRequest = BlobHttpWebRequestFactory.GetPageRanges(uri, BlobContext.Timeout, null, null, null, null, opContext); - BlobTests.SignRequest(newPageRangeRequest, BlobContext); - using (HttpWebResponse newPageRangeResponse = newPageRangeRequest.GetResponse() as HttpWebResponse) - { - GetPageRangesResponse getNewPageRangesResponse = new GetPageRangesResponse(newPageRangeResponse.GetResponseStream()); - newPageRanges.AddRange(getNewPageRangesResponse.PageRanges.ToList()); - } - - Assert.AreEqual(pageRanges.Count(), newPageRanges.Count() * 2); - for (int l = 0; l < newPageRanges.Count(); l++) - { - Assert.AreEqual(pageRanges[2 * l].StartOffset, newPageRanges[l].StartOffset); - Assert.AreEqual(pageRanges[2 * l].EndOffset, newPageRanges[l].EndOffset); - } - } - - public void GetBlobScenarioTest(string containerName, string blobName, BlobProperties properties, string leaseId, - byte[] content, HttpStatusCode? expectedError) - { - HttpWebRequest request = BlobTests.GetBlobRequest(BlobContext, containerName, blobName, AccessCondition.GenerateLeaseCondition(leaseId)); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.GetBlobResponse(response, BlobContext, properties, content, expectedError); - } - finally - { - response.Close(); - } - } - - /// - /// Sends a get blob range request with the given parameters and validates both request and response. - /// - /// The blob's container's name. - /// The blob's name. - /// The lease ID, or null if there is no lease. - /// The total contents of the blob. - /// The offset of the contents we will get. - /// The number of bytes we will get, or null to get the rest of the blob. - /// The error code we expect from this operation, or null if we expect it to succeed. - public void GetBlobRangeScenarioTest(string containerName, string blobName, string leaseId, byte[] content, long offset, long? count, HttpStatusCode? expectedError) - { - HttpWebRequest request = BlobTests.GetBlobRangeRequest(BlobContext, containerName, blobName, offset, count, AccessCondition.GenerateLeaseCondition(leaseId)); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - - try - { - long endRange = count.HasValue ? count.Value + offset - 1 : content.Length - 1; - byte[] selectedContent = null; - - // Compute expected content only if call is expected to succeed. - if (expectedError == null) - { - selectedContent = new byte[endRange - offset + 1]; - Array.Copy(content, offset, selectedContent, 0, selectedContent.Length); - } - - BlobTests.CheckBlobRangeResponse(response, BlobContext, selectedContent, offset, endRange, content.Length, expectedError); - } - finally - { - response.Close(); - } - } - - public void ListBlobsScenarioTest(string containerName, BlobListingContext listingContext, HttpStatusCode? expectedError, params string[] expectedBlobs) - { - HttpWebRequest request = BlobTests.ListBlobsRequest(BlobContext, containerName, listingContext); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.ListBlobsResponse(response, BlobContext, expectedError); - ListBlobsResponse listBlobsResponse = new ListBlobsResponse(response.GetResponseStream()); - int i = 0; - foreach (IListBlobEntry item in listBlobsResponse.Blobs) - { - ListBlobEntry blob = item as ListBlobEntry; - if (expectedBlobs == null) - { - Assert.Fail("Should not have blobs."); - } - Assert.IsTrue(i < expectedBlobs.Length, "Unexpected blob: " + blob.Name); - Assert.AreEqual(expectedBlobs[i++], blob.Name, "Incorrect blob."); - } - if (expectedBlobs != null && i < expectedBlobs.Length) - { - Assert.Fail("Missing blob: " + expectedBlobs[i] + "(and " + (expectedBlobs.Length - i - 1) + " more)."); - } - } - finally - { - response.Close(); - } - } - - public void ListContainersScenarioTest(ListingContext listingContext, HttpStatusCode? expectedError, params string[] expectedContainers) - { - HttpWebRequest request = BlobTests.ListContainersRequest(BlobContext, listingContext); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.ListContainersResponse(response, BlobContext, expectedError); - ListContainersResponse listContainersResponse = new ListContainersResponse(response.GetResponseStream()); - int i = 0; - foreach (BlobContainerEntry item in listContainersResponse.Containers) - { - if (expectedContainers == null) - { - Assert.Fail("Should not have containers."); - } - Assert.IsTrue(i < expectedContainers.Length, "Unexpected container: " + item.Name); - Assert.AreEqual(expectedContainers[i++], item.Name, "Incorrect container."); - } - if (expectedContainers != null && i < expectedContainers.Length) - { - Assert.Fail("Missing container: " + expectedContainers[i] + "(and " + (expectedContainers.Length - i - 1) + " more)."); - } - } - finally - { - response.Close(); - } - } - - public void PutBlockScenarioTest(string containerName, string blobName, string blockId, string leaseId, byte[] content, HttpStatusCode? expectedError) - { - HttpWebRequest request = BlobTests.PutBlockRequest(BlobContext, containerName, blobName, blockId, AccessCondition.GenerateLeaseCondition(leaseId)); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - request.ContentLength = content.Length; - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - BlobTestUtils.SetRequest(request, BlobContext, content); - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.PutBlockResponse(response, BlobContext, expectedError); - } - finally - { - response.Close(); - } - } - - public void PutBlockListScenarioTest(string containerName, string blobName, List blocks, BlobProperties blobProperties, string leaseId, HttpStatusCode? expectedError) - { - HttpWebRequest request = BlobTests.PutBlockListRequest(BlobContext, containerName, blobName, blobProperties, AccessCondition.GenerateLeaseCondition(leaseId)); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - byte[] content; - using (MemoryStream stream = new MemoryStream()) - { - BlobRequest.WriteBlockListBody(blocks, stream); - stream.Seek(0, SeekOrigin.Begin); - content = new byte[stream.Length]; - stream.Read(content, 0, content.Length); - } - request.ContentLength = content.Length; - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - BlobTestUtils.SetRequest(request, BlobContext, content); - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.PutBlockListResponse(response, BlobContext, expectedError); - } - finally - { - response.Close(); - } - } - - public void GetBlockListScenarioTest(string containerName, string blobName, BlockListingFilter typesOfBlocks, string leaseId, HttpStatusCode? expectedError, params string[] expectedBlocks) - { - HttpWebRequest request = BlobTests.GetBlockListRequest(BlobContext, containerName, blobName, typesOfBlocks, AccessCondition.GenerateLeaseCondition(leaseId)); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, BlobContext); - } - HttpWebResponse response = BlobTestUtils.GetResponse(request, BlobContext); - try - { - BlobTests.GetBlockListResponse(response, BlobContext, expectedError); - GetBlockListResponse getBlockListResponse = new GetBlockListResponse(response.GetResponseStream()); - int i = 0; - foreach (ListBlockItem item in getBlockListResponse.Blocks) - { - if (expectedBlocks == null) - { - Assert.Fail("Should not have blocks."); - } - Assert.IsTrue(i < expectedBlocks.Length, "Unexpected block: " + item.Name); - Assert.AreEqual(expectedBlocks[i++], item.Name, "Incorrect block."); - } - if (expectedBlocks != null && i < expectedBlocks.Length) - { - Assert.Fail("Missing block: " + expectedBlocks[i] + "(and " + (expectedBlocks.Length - i - 1) + " more)."); - } - } - finally - { - response.Close(); - } - } - - public static Uri ConstructUri(string address, params string[] folders) - { - Assert.IsNotNull(address); - - string uriString = address; - foreach (string folder in folders) - { - uriString = String.Format("{0}/{1}", uriString, folder); - } - Uri uri = null; - uri = new Uri(uriString); - return uri; - } - - public void CopyFromToRestoreSnapshot(BlobContext context, string containerName, string blobName) - { - string oldText = "Old stuff"; - string newText = "New stuff"; - - StorageCredentials accountAndKey = new StorageCredentials(context.Account, context.Key); - CloudStorageAccount account = new CloudStorageAccount(accountAndKey, false); - CloudBlobClient blobClient = new CloudBlobClient(new Uri(context.Address), account.Credentials); - CloudBlobContainer container = blobClient.GetContainerReference(containerName); - CloudBlockBlob blob = container.GetBlockBlobReference(blobName); - BlobTestBase.UploadText(blob, oldText, Encoding.UTF8); - CloudBlockBlob snapshot = blob.CreateSnapshot(); - Assert.IsNotNull(snapshot.SnapshotTime); - BlobTestBase.UploadText(blob, newText, Encoding.UTF8); - - Uri sourceUri = new Uri(snapshot.Uri.AbsoluteUri + "?snapshot=" + BlobRequest.ConvertDateTimeToSnapshotString(snapshot.SnapshotTime.Value)); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = BlobHttpWebRequestFactory.CopyFrom(blob.Uri, 30, sourceUri, null, null, opContext); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - BlobTests.SignRequest(request, context); - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); - Assert.AreEqual(response.StatusCode, HttpStatusCode.Accepted); - - string text = BlobTestBase.DownloadText(blob, Encoding.UTF8); - Assert.AreEqual(text, oldText); - - blob.Delete(DeleteSnapshotsOption.IncludeSnapshots, null, null); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobContext.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobContext.cs deleted file mode 100644 index 871059af1cdf2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobContext.cs +++ /dev/null @@ -1,70 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Auth; -using System; - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - internal class BlobContext - { - public int Timeout { get; private set; } - - public bool IsAsync { get; private set; } - - public string Account - { - get - { - return owner ? TestBase.TargetTenantConfig.AccountName : null; - } - } - - public byte[] Key - { - get - { - return owner ? Convert.FromBase64String(TestBase.TargetTenantConfig.AccountKey) : null; - } - } - - public StorageCredentials Credentials - { - get - { - return owner ? new StorageCredentials(Account, Key) : null; - } - } - - public string Address - { - get - { - return TestBase.TargetTenantConfig.BlobServiceEndpoint; - } - } - - private bool owner; - - public BlobContext(bool owner, bool isAsync, int timeout) - { - this.Timeout = timeout; - this.owner = owner; - this.IsAsync = isAsync; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobProtocolTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobProtocolTest.cs deleted file mode 100644 index 14ff98dbceee6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobProtocolTest.cs +++ /dev/null @@ -1,537 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - [TestClass] - public class BlobProtocolTest : TestBase - { - private static Random random = new Random(); - - private static BlobClientTests cloudOwnerSync = new BlobClientTests(true, false, 30); - private static BlobClientTests cloudAnonSync = new BlobClientTests(false, false, 30); - private static BlobClientTests cloudOwnerAsync = new BlobClientTests(true, false, 30); - private static BlobClientTests cloudAnonAsync = new BlobClientTests(false, false, 30); - - private static BlobClientTests cloudSetup = new BlobClientTests(true, false, 30); - - [ClassInitialize] - public static void InitialInitialize(TestContext testContext) - { - cloudSetup.Initialize(); - } - - [ClassCleanup] - public static void FinalCleanup() - { - cloudSetup.Cleanup(); - - // sleep for 40s so that if the test is re-run, we can recreate the container - Thread.Sleep(35000); - } - - #region PutPageBlob - [TestMethod] - [Description("owner, sync : Make a valid Put Index Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutPageBlobCloudOwnerSync() - { - BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; - cloudOwnerSync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), properties, BlobType.PageBlob, new byte[0], HttpStatusCode.Created); - } - - [TestMethod] - [Description("anonymous, sync : Make an invalid Put Index Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutPageBlobCloudAnonSync() - { - BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; - cloudAnonSync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), - properties, BlobType.PageBlob, new byte[0], HttpStatusCode.NotFound); - } - - [TestMethod] - [Description("owner, isAsync : Make a valid Put Index Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutPageBlobCloudOwnerAsync() - { - BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; - cloudOwnerAsync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), properties, BlobType.PageBlob, new byte[0], HttpStatusCode.Created); - } - - [TestMethod] - [Description("anonymous, isAsync : Make an invalid Put Index Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutPageBlobCloudAnonAsync() - { - BlobProperties properties = new BlobProperties() { BlobType = BlobType.PageBlob }; - cloudAnonAsync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), - properties, BlobType.PageBlob, new byte[0], HttpStatusCode.NotFound); - } - #endregion - - #region PutBlockBlob - [TestMethod] - [Description("owner, sync : Make a valid Put Stream Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutBlockBlobCloudOwnerSync() - { - byte[] content = new byte[6000]; - random.NextBytes(content); - BlobProperties properties = new BlobProperties() { BlobType = BlobType.BlockBlob }; - cloudOwnerSync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), properties, BlobType.BlockBlob, content, null); - } - - [TestMethod] - [Description("anonymous, sync : Make an invalid Put Stream Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutBlockBlobCloudAnonSync() - { - byte[] content = new byte[6000]; - random.NextBytes(content); - BlobProperties properties = new BlobProperties() { BlobType = BlobType.BlockBlob }; - cloudAnonSync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), - properties, BlobType.BlockBlob, content, HttpStatusCode.NotFound); - } - - [TestMethod] - [Description("owner, isAsync : Make a valid Put Stream Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutBlockBlobCloudOwnerAsync() - { - byte[] content = new byte[6000]; - random.NextBytes(content); - BlobProperties properties = new BlobProperties() { BlobType = BlobType.BlockBlob }; - cloudOwnerAsync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), properties, BlobType.BlockBlob, content, null); - } - - [TestMethod] - [Description("anonymous, isAsync : Make an invalid Put Stream Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutBlockBlobCloudAnonAsync() - { - byte[] content = new byte[6000]; - random.NextBytes(content); - BlobProperties properties = new BlobProperties() { BlobType = BlobType.BlockBlob }; - cloudAnonAsync.PutBlobScenarioTest(cloudSetup.ContainerName, Guid.NewGuid().ToString(), - properties, BlobType.BlockBlob, content, HttpStatusCode.NotFound); - } - #endregion - - #region Blob - [TestMethod] - [Description("owner, sync : Make a valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobCloudOwnerSync() - { - cloudOwnerSync.GetBlobScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("owner, isAsync : Make a valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobCloudOwnerAsync() - { - cloudOwnerAsync.GetBlobScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("anonymous, sync : Make an invalid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobCloudAnonSync() - { - cloudAnonSync.GetBlobScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, HttpStatusCode.NotFound); - } - - [TestMethod] - [Description("anonymous, isAsync : Make an invalid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobCloudAnonAsync() - { - cloudAnonAsync.GetBlobScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, HttpStatusCode.NotFound); - } - - [TestMethod] - [Description("owner, sync : Make a public valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetPublicBlobCloudOwnerSync() - { - cloudOwnerSync.GetBlobScenarioTest(cloudSetup.PublicContainerName, cloudSetup.PublicBlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("owner, isAsync : Make a public valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetPublicBlobCloudOwnerAsync() - { - cloudOwnerAsync.GetBlobScenarioTest(cloudSetup.PublicContainerName, cloudSetup.PublicBlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("anonymous, sync : Make a public valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetPublicBlobCloudAnonSync() - { - cloudAnonSync.GetBlobScenarioTest(cloudSetup.PublicContainerName, cloudSetup.PublicBlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("anonymous, isAsync : Make a public valid Get Blob request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetPublicBlobCloudAnonAsync() - { - cloudAnonAsync.GetBlobScenarioTest(cloudSetup.PublicContainerName, cloudSetup.PublicBlobName, cloudSetup.Properties, - cloudSetup.LeaseId, cloudSetup.Content, null); - } - - [TestMethod] - [Description("owner, sync, range : Make valid Get Blob range requests and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobRangeCloudOwnerSync() - { - int all = cloudSetup.Content.Length; - int quarter = cloudSetup.Content.Length / 4; - int half = cloudSetup.Content.Length / 2; - - // Full content, as complete range. (0-end) - cloudOwnerSync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, 0, all, null); - - // Partial content, as complete range. (quarter-quarterPlusHalf) - cloudOwnerSync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, quarter, half, null); - - // Full content, as open range. (0-) - cloudOwnerSync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, 0, null, null); - - // Partial content, as open range. (half-) - cloudOwnerSync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, half, null, null); - } - - [TestMethod] - [Description("owner, sync, range : Make a Get Blob range request with an invalid range")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobRangeCloudOwnerSyncInvalidRange() - { - int all = cloudSetup.Content.Length; - - // Invalid range starting after the end of the blob (endPlusOne-) - cloudOwnerSync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, all, null, HttpStatusCode.RequestedRangeNotSatisfiable); - } - - [TestMethod] - [Description("owner, isAsync, range : Make valid Get Blob range requests and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetBlobRangeCloudOwnerAsync() - { - int all = cloudSetup.Content.Length; - int quarter = cloudSetup.Content.Length / 4; - int half = cloudSetup.Content.Length / 2; - - // Full content, as complete range. (0-end) - cloudOwnerAsync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, 0, all, null); - - // Partial content, as complete range. (quarter-quarterPlusHalf) - cloudOwnerAsync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, quarter, half, null); - - // Full content, as open range. (0-) - cloudOwnerAsync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, 0, null, null); - - // Partial content, as open range. (half-) - cloudOwnerAsync.GetBlobRangeScenarioTest(cloudSetup.ContainerName, cloudSetup.BlobName, cloudSetup.LeaseId, cloudSetup.Content, half, null, null); - } - #endregion - - #region ListBlobs - [TestMethod] - [Description("anonymous, sync : Make a valid List Blobs request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolListBlobsCloudAnonSync() - { - BlobListingContext listingContext = new BlobListingContext("p", null, null, BlobListingDetails.All); - cloudAnonSync.ListBlobsScenarioTest(cloudSetup.PublicContainerName, listingContext, null, cloudSetup.PublicBlobName); - - cloudSetup.CreateBlob(cloudSetup.PublicContainerName, "newblob1", true); - cloudSetup.CreateBlob(cloudSetup.PublicContainerName, "newblob2", true); - - try - { - cloudAnonSync.ListBlobsScenarioTest(cloudSetup.PublicContainerName, listingContext, null, cloudSetup.PublicBlobName); - - // snapshots cannot be listed along with delimiter - listingContext = new BlobListingContext("n", 10, "/", BlobListingDetails.Metadata); - cloudAnonSync.ListBlobsScenarioTest(cloudSetup.PublicContainerName, listingContext, null, "newblob1", "newblob2"); - } - finally - { - cloudSetup.DeleteBlob(cloudSetup.PublicContainerName, "newblob1"); - cloudSetup.DeleteBlob(cloudSetup.PublicContainerName, "newblob2"); - } - } - - [TestMethod] - [Description("owner, sync : Make a valid List Blobs request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolListBlobsCloudOwnerSync() - { - BlobListingContext listingContext = new BlobListingContext("def", null, null, BlobListingDetails.All); - cloudOwnerSync.ListBlobsScenarioTest(cloudSetup.ContainerName, listingContext, null, cloudSetup.BlobName); - - cloudSetup.CreateBlob(cloudSetup.ContainerName, "newblob1", false); - cloudSetup.CreateBlob(cloudSetup.ContainerName, "newblob2", false); - - try - { - cloudOwnerSync.ListBlobsScenarioTest(cloudSetup.ContainerName, listingContext, null, cloudSetup.BlobName); - listingContext = new BlobListingContext("n", 10, "/", BlobListingDetails.Metadata); - cloudOwnerSync.ListBlobsScenarioTest(cloudSetup.ContainerName, listingContext, null, "newblob1", "newblob2"); - } - finally - { - cloudSetup.DeleteBlob(cloudSetup.ContainerName, "newblob1"); - cloudSetup.DeleteBlob(cloudSetup.ContainerName, "newblob2"); - } - } - #endregion - - #region ListContainers - [TestMethod] - [Description("cloud: Make a valid List Containers request and get the response")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolListContainersCloud() - { - ListingContext listingContext = new ListingContext("default", null); - cloudOwnerAsync.ListContainersScenarioTest(listingContext, null, cloudSetup.ContainerName); - - cloudSetup.CreateContainer("newcontainer1", true); - cloudSetup.CreateContainer("newcontainer2", true); - - try - { - cloudOwnerAsync.ListContainersScenarioTest(listingContext, null, cloudSetup.ContainerName); - listingContext = new ListingContext("newcontainer", 10); - cloudOwnerAsync.ListContainersScenarioTest(listingContext, null, "newcontainer1", "newcontainer2"); - } - finally - { - cloudSetup.DeleteContainer("newcontainer1"); - cloudSetup.DeleteContainer("newcontainer2"); - } - } - - [TestMethod] - [Description("Get a container with empty header excluded/included from signature and verify request succeeded")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolGetContainerWithEmptyHeader() - { - ListingContext listingContext = new ListingContext("default", null); - cloudOwnerAsync.CreateContainer("emptyheadercontainer", true); - - HttpWebRequest request = BlobTests.ListContainersRequest(cloudOwnerAsync.BlobContext, listingContext); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (cloudOwnerAsync.BlobContext.Credentials != null) - { - BlobTests.SignRequest(request, cloudOwnerAsync.BlobContext); - request.Headers.Add("x-ms-blob-application-metadata", ""); - } - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, cloudOwnerAsync.BlobContext)) - { - BlobTests.ListContainersResponse(response, cloudOwnerAsync.BlobContext, null); - } - - request = BlobTests.ListContainersRequest(cloudOwnerAsync.BlobContext, listingContext); - Assert.IsTrue(request != null, "Failed to create HttpWebRequest"); - if (cloudOwnerAsync.BlobContext.Credentials != null) - { - request.Headers.Add("x-ms-blob-application-metadata", ""); - BlobTests.SignRequest(request, cloudOwnerAsync.BlobContext); - } - using (HttpWebResponse response = BlobTestUtils.GetResponse(request, cloudOwnerAsync.BlobContext)) - { - BlobTests.ListContainersResponse(response, cloudOwnerAsync.BlobContext, HttpStatusCode.OK); - } - } - #endregion - - #region PutBlock, DownloadBlockList, and PutBlockList - [TestMethod] - [Description("owner, isAsync : PutBlock, DownloadBlockList, and PutBlockList scenarios")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutGetBlockListCloudOwnerAsync() - { - string blockId1 = Convert.ToBase64String(new byte[] { 99, 100, 101 }); - string blockId2 = Convert.ToBase64String(new byte[] { 102, 103, 104 }); - - // use a unique name since temp blocks from previous runs can exist - string blobName = "blob1" + DateTime.UtcNow.Ticks; - BlobProperties blobProperties = new BlobProperties(); - List blocks = new List(); - PutBlockListItem block1 = new PutBlockListItem(blockId1, BlockSearchMode.Uncommitted); - blocks.Add(block1); - PutBlockListItem block2 = new PutBlockListItem(blockId2, BlockSearchMode.Uncommitted); - blocks.Add(block2); - try - { - cloudOwnerAsync.PutBlockScenarioTest(cloudSetup.ContainerName, blobName, blockId1, cloudSetup.LeaseId, cloudSetup.Content, null); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null, blockId1); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null); - - cloudOwnerAsync.PutBlockScenarioTest(cloudSetup.ContainerName, blobName, blockId2, cloudSetup.LeaseId, cloudSetup.Content, null); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null); - - cloudOwnerAsync.PutBlockListScenarioTest(cloudSetup.ContainerName, blobName, blocks, blobProperties, cloudSetup.LeaseId, null); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null); - cloudOwnerAsync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null, blockId1, blockId2); - } - finally - { - cloudOwnerAsync.DeleteBlob(cloudSetup.ContainerName, blobName); - } - } - - [TestMethod] - [Description("owner, sync : PutBlock, DownloadBlockList, and PutBlockList scenarios")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void BlobProtocolPutGetBlockListCloudOwnerSync() - { - string blockId1 = Convert.ToBase64String(new byte[] { 99, 100, 101 }); - string blockId2 = Convert.ToBase64String(new byte[] { 102, 103, 104 }); - - // use a unique name since temp blocks from previous runs can exist - string blobName = "blob2" + DateTime.UtcNow.Ticks; - BlobProperties blobProperties = new BlobProperties(); - List blocks = new List(); - PutBlockListItem block1 = new PutBlockListItem(blockId1, BlockSearchMode.Uncommitted); - blocks.Add(block1); - PutBlockListItem block2 = new PutBlockListItem(blockId2, BlockSearchMode.Uncommitted); - blocks.Add(block2); - try - { - cloudOwnerSync.PutBlockScenarioTest(cloudSetup.ContainerName, blobName, blockId1, cloudSetup.LeaseId, cloudSetup.Content, null); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null, blockId1); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null); - - cloudOwnerSync.PutBlockScenarioTest(cloudSetup.ContainerName, blobName, blockId2, cloudSetup.LeaseId, cloudSetup.Content, null); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null); - - cloudOwnerSync.PutBlockListScenarioTest(cloudSetup.ContainerName, blobName, blocks, blobProperties, cloudSetup.LeaseId, null); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.All, cloudSetup.LeaseId, null, blockId1, blockId2); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Uncommitted, cloudSetup.LeaseId, null); - cloudOwnerSync.GetBlockListScenarioTest(cloudSetup.ContainerName, blobName, BlockListingFilter.Committed, cloudSetup.LeaseId, null, blockId1, blockId2); - } - finally - { - cloudOwnerSync.DeleteBlob(cloudSetup.ContainerName, blobName); - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTestUtils.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTestUtils.cs deleted file mode 100644 index 312b4b093c9bd..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTestUtils.cs +++ /dev/null @@ -1,509 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Text.RegularExpressions; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - internal class BlobTestUtils - { - #region Request Validation - - public static void DateHeader(HttpWebRequest request, bool required) - { - bool standardHeader = request.Headers[HttpRequestHeader.Date] != null; - bool msHeader = request.Headers["x-ms-date"] != null; - - Assert.IsFalse(standardHeader && msHeader); - Assert.IsFalse(required && !(standardHeader ^ msHeader)); - - if (request.Headers[HttpRequestHeader.Date] != null) - { - try - { - DateTime parsed = DateTime.Parse(request.Headers[HttpRequestHeader.Date]).ToUniversalTime(); - } - catch (Exception) - { - Assert.Fail(); - } - } - else if (request.Headers[HttpRequestHeader.Date] != null) - { - try - { - DateTime parsed = DateTime.Parse(request.Headers["x-ms-date"]).ToUniversalTime(); - } - catch (Exception) - { - Assert.Fail(); - } - } - } - - public static void VersionHeader(HttpWebRequest request, bool required) - { - Assert.IsFalse(required && (request.Headers["x-ms-version"] == null)); - if (request.Headers["x-ms-version"] != null) - { - Assert.AreEqual("2012-02-12", request.Headers["x-ms-version"]); - } - } - - public static void ContentLengthHeader(HttpWebRequest request, long expectedValue) - { - Assert.AreEqual(expectedValue, request.ContentLength); - } - - public static void ContentTypeHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.ContentType == null)); - if (request.ContentType != null) - { - Assert.AreEqual(expectedValue, request.ContentType); - } - } - - public static void ContentEncodingHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers[HttpRequestHeader.ContentEncoding] == null)); - if (request.Headers[HttpRequestHeader.ContentEncoding] != null) - { - Assert.AreEqual(expectedValue, request.Headers[HttpRequestHeader.ContentEncoding]); - } - } - - public static void ContentLanguageHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers[HttpRequestHeader.ContentLanguage] == null)); - if (request.Headers[HttpRequestHeader.ContentLanguage] != null) - { - Assert.AreEqual(expectedValue, request.Headers[HttpRequestHeader.ContentLanguage]); - } - } - - public static void ContentMd5Header(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers[HttpRequestHeader.ContentMd5] == null)); - if (request.Headers[HttpRequestHeader.ContentMd5] != null) - { - Assert.AreEqual(expectedValue, request.Headers[HttpRequestHeader.ContentMd5]); - } - } - - public static void CacheControlHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers[HttpRequestHeader.CacheControl] == null)); - if (request.Headers[HttpRequestHeader.CacheControl] != null) - { - Assert.AreEqual(expectedValue, request.Headers[HttpRequestHeader.CacheControl]); - } - } - - public static void BlobTypeHeader(HttpWebRequest request, BlobType? expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-blob-type"] == null)); - if (request.Headers["x-ms-blob-type"] != null) - { - string blobTypeString = request.Headers["x-ms-blob-type"]; - Assert.IsNotNull(blobTypeString); - BlobType? blobType = null; - switch (blobTypeString) - { - case "PageBlob": - blobType = BlobType.PageBlob; - break; - case "BlockBlob": - blobType = BlobType.BlockBlob; - break; - } - - Assert.AreEqual(expectedValue, blobType); - } - } - - public static void BlobSizeHeader(HttpWebRequest request, long? expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-blob-content-length"] == null)); - if (request.Headers["x-ms-blob-content-length"] != null) - { - long? parsed = long.Parse(request.Headers["x-ms-blob-content-length"]); - Assert.IsNotNull(parsed); - Assert.AreEqual(expectedValue, parsed); - } - } - - /// - /// Tests for a range header in an HTTP request, where no end range is expected. - /// - /// The HTTP request. - /// The expected beginning of the range, or null if no range is expected. - public static void RangeHeader(HttpWebRequest request, long? expectedStart) - { - RangeHeader(request, expectedStart, null); - } - - /// - /// Tests for a range header in an HTTP request. - /// - /// The HTTP request. - /// The expected beginning of the range, or null if no range is expected. - /// The expected end of the range, or null if no end is expected. - public static void RangeHeader(HttpWebRequest request, long? expectedStart, long? expectedEnd) - { - // The range in "x-ms-range" is used if it exists, or else "Range" is used. - string requestRange = request.Headers["x-ms-range"] ?? request.Headers[HttpRequestHeader.Range]; - - // We should find a range if and only if we expect one. - Assert.AreEqual(expectedStart.HasValue, requestRange != null); - - // If we expect a range, the range we find should be identical. - if (expectedStart.HasValue) - { - string rangeStart = expectedStart.Value.ToString(); - string rangeEnd = expectedEnd.HasValue ? expectedEnd.Value.ToString() : string.Empty; - string expectedValue = string.Format("bytes={0}-{1}", rangeStart, rangeEnd); - Assert.AreEqual(expectedValue.ToString(), requestRange); - } - } - - public static void SetRequest(HttpWebRequest request, BlobContext context, byte[] content) - { - Assert.IsNotNull(request); - if (context.IsAsync) - { - BlobTestUtils.SetRequestAsync(request, context, content); - } - else - { - BlobTestUtils.SetRequestSync(request, context, content); - } - } - - static AutoResetEvent setRequestAsyncSem = new AutoResetEvent(false); - static Stream setRequestAsyncStream; - static void SetRequestAsync(HttpWebRequest request, BlobContext context, byte[] content) - { - request.BeginGetRequestStream(new AsyncCallback(BlobTestUtils.ReadCallback), request); - setRequestAsyncSem.WaitOne(); - Assert.IsNotNull(setRequestAsyncStream); - setRequestAsyncStream.Write(content, 0, content.Length); - setRequestAsyncStream.Close(); - } - - static void ReadCallback(IAsyncResult result) - { - HttpWebRequest request = (HttpWebRequest)result.AsyncState; - setRequestAsyncStream = request.EndGetRequestStream(result); - setRequestAsyncSem.Set(); - } - - static void SetRequestSync(HttpWebRequest request, BlobContext context, byte[] content) - { - Stream stream = request.GetRequestStream(); - Assert.IsNotNull(stream); - stream.Write(content, 0, content.Length); - stream.Close(); - } - - #endregion - - #region Response Validation - - /// - /// Tests for a content range header in an HTTP response. - /// - /// The HTTP response. - /// The expected beginning of the range. - /// The expected end of the range. - /// The expected total number of bytes in the range. - public static void ContentRangeHeader(HttpWebResponse response, long expectedStart, long expectedEnd, long expectedTotal) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.ContentRange]); - string expectedRange = string.Format("bytes {0}-{1}/{2}", expectedStart, expectedEnd, expectedTotal); - Assert.AreEqual(expectedRange, response.Headers[HttpResponseHeader.ContentRange]); - } - - /// - /// Validates a lease ID header in a request. - /// - /// The request. - /// The expected value. - public static void LeaseIdHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-lease-id"] == null)); - if (request.Headers["x-ms-lease-id"] != null) - { - Assert.AreEqual(expectedValue, request.Headers["x-ms-lease-id"]); - } - } - - /// - /// Validates a lease action header in a request. - /// - /// The request. - /// The expected value. - public static void LeaseActionHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-lease-action"] == null)); - if (request.Headers["x-ms-lease-action"] != null) - { - Assert.AreEqual(expectedValue, request.Headers["x-ms-lease-action"]); - } - } - - /// - /// Validates a proposed lease ID header in a request. - /// - /// The request. - /// The expected value. - public static void ProposedLeaseIdHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-proposed-lease-id"] == null)); - if (request.Headers["x-ms-proposed-lease-id"] != null) - { - Assert.AreEqual(expectedValue, request.Headers["x-ms-proposed-lease-id"]); - } - } - - /// - /// Validates a lease duration header in a request. - /// - /// The request. - /// The expected value. - public static void LeaseDurationHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-lease-duration"] == null)); - if (request.Headers["x-ms-lease-duration"] != null) - { - Assert.AreEqual(expectedValue, request.Headers["x-ms-lease-duration"]); - } - } - - /// - /// Validates a break period header in a request. - /// - /// The request. - /// The expected value. - public static void BreakPeriodHeader(HttpWebRequest request, string expectedValue) - { - Assert.IsFalse((expectedValue != null) && (request.Headers["x-ms-lease-break-period"] == null)); - if (request.Headers["x-ms-lease-break-period"] != null) - { - Assert.AreEqual(expectedValue, request.Headers["x-ms-lease-break-period"]); - } - } - - public static void AuthorizationHeader(HttpWebRequest request, bool required, string account) - { - Assert.IsFalse(required && (request.Headers[HttpRequestHeader.Authorization] == null)); - if (request.Headers[HttpRequestHeader.Authorization] != null) - { - string authorization = request.Headers[HttpRequestHeader.Authorization]; - string pattern = String.Format("^(SharedKey|SharedKeyLite) {0}:[0-9a-zA-Z\\+/=]{{20,}}$", account); - Regex authorizationRegex = new Regex(pattern); - Assert.IsTrue(authorizationRegex.IsMatch(authorization)); - } - } - - public static void ETagHeader(HttpWebResponse response) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.ETag]); - Regex eTagRegex = new Regex(@"^""0x[A-F0-9]{15,}""$"); - Assert.IsTrue(eTagRegex.IsMatch(response.Headers[HttpResponseHeader.ETag])); - } - - public static void LastModifiedHeader(HttpWebResponse response) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.LastModified]); - try - { - DateTime parsed = DateTime.Parse(response.Headers[HttpResponseHeader.LastModified]).ToUniversalTime(); - } - catch (Exception) - { - Assert.Fail(); - } - } - - public static void ContentMd5Header(HttpWebResponse response) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.ContentMd5]); - } - - public static void RequestIdHeader(HttpWebResponse response) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers["x-ms-request-id"]); - } - - public static void ContentLengthHeader(HttpWebResponse response, long expectedValue) - { - Assert.IsNotNull(response); - Assert.AreEqual(expectedValue, response.ContentLength); - } - - public static void ContentTypeHeader(HttpWebResponse response, string expectedValue) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.ContentType); - Assert.AreEqual(expectedValue, response.ContentType); - } - - public static void ContentRangeHeader(HttpWebResponse response, PageRange expectedValue) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.ContentRange]); - Assert.AreEqual(expectedValue.ToString(), response.Headers[HttpResponseHeader.ContentRange]); - } - - public static void ContentEncodingHeader(HttpWebResponse response, string expectedValue) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.ContentEncoding); - Assert.AreEqual(expectedValue, response.ContentEncoding); - } - - public static void ContentLanguageHeader(HttpWebResponse response, string expectedValue) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.ContentLanguage]); - Assert.AreEqual(expectedValue, response.Headers[HttpResponseHeader.ContentLanguage]); - } - - public static void CacheControlHeader(HttpWebResponse response, string expectedValue) - { - Assert.IsNotNull(response); - Assert.IsNotNull(response.Headers[HttpResponseHeader.CacheControl]); - Assert.AreEqual(expectedValue, response.Headers[HttpResponseHeader.CacheControl]); - } - - public static void BlobTypeHeader(HttpWebResponse response, BlobType expectedValue) - { - Assert.IsNotNull(response); - string header = response.Headers["x-ms-blob-type"]; - BlobType? parsed = null; - switch (header) - { - case "BlockBlob": - parsed = BlobType.BlockBlob; - break; - case "PageBlob": - parsed = BlobType.PageBlob; - break; - } - Assert.IsNotNull(parsed); - Assert.AreEqual(expectedValue, parsed); - } - - /// - /// Validates a lease time header in a response. - /// - /// The response. - /// The expected value. - /// The margin of error in the value. - public static void LeaseTimeHeader(HttpWebResponse response, int? expectedValue, int? errorMargin) - { - int? leaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(response); - Assert.IsFalse((expectedValue != null) && (leaseTime == null)); - if (leaseTime != null) - { - int error = Math.Abs(expectedValue.Value - leaseTime.Value); - Assert.IsTrue(error < errorMargin, "Lease Time header is not within expected range."); - } - } - - /// - /// Validates a lease ID header in a response. - /// - /// The response. - /// The expected value. - public static void LeaseIdHeader(HttpWebResponse response, string expectedValue) - { - string leaseId = BlobHttpResponseParsers.GetLeaseId(response); - Assert.IsFalse((expectedValue != null) && (leaseId == null)); - if (leaseId != null) - { - LeaseIdHeader(response); - Assert.AreEqual(expectedValue, leaseId); - } - } - - /// - /// Validates a lease ID header in a response. - /// - /// The response. - public static void LeaseIdHeader(HttpWebResponse response) - { - string leaseId = BlobHttpResponseParsers.GetLeaseId(response); - Assert.IsNotNull(leaseId); - Assert.IsTrue(BlobTests.LeaseIdValidator(AccessCondition.GenerateLeaseCondition(leaseId))); - } - - public static void Contents(HttpWebResponse response, byte[] expectedContent) - { - Assert.IsNotNull(response); - Assert.IsTrue(response.ContentLength >= 0); - byte[] buf = new byte[response.ContentLength]; - Stream stream = response.GetResponseStream(); - // Have to read one byte each time because of an issue of this stream. - for (int i = 0; i < buf.Length; i++) - { - buf[i] = (byte)(stream.ReadByte()); - } - stream.Close(); - Assert.IsTrue(buf.SequenceEqual(expectedContent)); - } - - #endregion - - #region Helpers - - public static HttpWebResponse GetResponse(HttpWebRequest request, BlobContext context) - { - Assert.IsNotNull(request); - HttpWebResponse response = null; - try - { - response = (HttpWebResponse)request.GetResponse(); - } - catch (WebException ex) - { - response = (HttpWebResponse)ex.Response; - } - Assert.IsNotNull(response); - return response; - } - - public static bool ContentValidator(byte[] content) - { - return content != null; - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTests.cs deleted file mode 100644 index 58949615147d0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/Protocol/BlobTests.cs +++ /dev/null @@ -1,950 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Auth.Protocol; -using Microsoft.WindowsAzure.Storage.Core.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; - -namespace Microsoft.WindowsAzure.Storage.Blob.Protocol -{ - internal class BlobTests - { - public static HttpWebRequest PutBlobRequest(BlobContext context, string containerName, string blobName, - BlobProperties properties, BlobType blobType, byte[] content, long pageBlobSize, AccessCondition accessCondition) - { - bool valid = BlobTests.ContainerNameValidator(containerName) && - BlobTests.BlobNameValidator(blobName) && - BlobTests.PutPropertiesValidator(properties) && - BlobTestUtils.ContentValidator(content); - - bool fatal = !BlobTests.PutPropertiesValidator(properties); - - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - HttpWebRequest request = null; - OperationContext opContext = new OperationContext(); - try - { - request = BlobHttpWebRequestFactory.Put(uri, context.Timeout, properties, blobType, pageBlobSize, accessCondition, opContext); - if (fatal) - { - Assert.Fail(); - } - } - catch (InvalidOperationException) - { - if (valid) - { - Assert.Fail(); - } - } - if (valid) - { - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.ContentTypeHeader(request, null); - BlobTestUtils.ContentEncodingHeader(request, properties.ContentEncoding); - BlobTestUtils.ContentLanguageHeader(request, null); - BlobTestUtils.ContentMd5Header(request, null); - BlobTestUtils.CacheControlHeader(request, null); - BlobTestUtils.BlobTypeHeader(request, properties.BlobType); - BlobTestUtils.BlobSizeHeader(request, (properties.BlobType == BlobType.PageBlob) ? properties.Length : (long?)null); - } - return request; - } - - public static void PutBlobResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, response.StatusDescription); - BlobTestUtils.ETagHeader(response); - BlobTestUtils.LastModifiedHeader(response); - BlobTestUtils.ContentMd5Header(response); - BlobTestUtils.RequestIdHeader(response); - BlobTestUtils.ContentLengthHeader(response, -1); //Should this be -1 or 0? - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - response.Close(); - } - - public static HttpWebRequest GetBlobRequest(BlobContext context, string containerName, string blobName, AccessCondition accessCondition) - { - bool valid = BlobTests.ContainerNameValidator(containerName) && - BlobTests.BlobNameValidator(blobName) && - BlobTests.LeaseIdValidator(accessCondition); - - Uri uri = BlobTests.ConstructGetUri(context.Address, containerName, blobName); - HttpWebRequest request = null; - OperationContext opContext = new OperationContext(); - try - { - request = BlobHttpWebRequestFactory.Get(uri, context.Timeout, null /* snapshot */, accessCondition, opContext); - } - catch (InvalidOperationException) - { - if (valid) - { - Assert.Fail(); - } - } - if (valid) - { - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("GET", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId); - } - return request; - } - - public static void GetBlobResponse(HttpWebResponse response, BlobContext context, BlobProperties properties, byte[] content, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); - BlobTestUtils.LastModifiedHeader(response); - BlobTestUtils.ContentLengthHeader(response, content.Length); - BlobTestUtils.ETagHeader(response); - BlobTestUtils.RequestIdHeader(response); - BlobTestUtils.Contents(response, content); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - response.Close(); - } - - /// - /// Generates a get blob request over the specified range, and checks the request for consistency. - /// - /// The testing context. - /// The name of the container. - /// The name of the blob. - /// The offset to the range. - /// The number of elements in the range. - /// The lease ID, or null if the blob is not leased. - /// A web request for getting a blob range. - public static HttpWebRequest GetBlobRangeRequest(BlobContext context, string containerName, string blobName, long offset, long? count, AccessCondition accessCondition) - { - bool valid = BlobTests.ContainerNameValidator(containerName) && - BlobTests.BlobNameValidator(blobName) && - BlobTests.LeaseIdValidator(accessCondition); - - Uri uri = BlobTests.ConstructGetUri(context.Address, containerName, blobName); - HttpWebRequest request = null; - OperationContext opContext = new OperationContext(); - - try - { - request = BlobHttpWebRequestFactory.Get(uri, context.Timeout, null /* snapshot */, offset, count, false, accessCondition, opContext); - } - catch (InvalidOperationException) - { - if (valid) - { - Assert.Fail(); - } - } - - if (valid) - { - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("GET", request.Method); - BlobTestUtils.RangeHeader(request, offset, count.HasValue ? (long?)(count.Value + offset - 1) : null); - BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId); - } - - return request; - } - - /// - /// Checks a get blob range response for consistency with the given parameters, and closes the response. - /// - /// The HTTP web response to check. - /// The testing context. - /// The expected content returned in the response. - /// The expected start range returned in the response header. - /// The expected end range returned in the response header. - /// The expected total number of bytes in the blob. - /// The expected error code, or null if the operation is expected to succeed. - public static void CheckBlobRangeResponse( - HttpWebResponse response, - BlobContext context, - byte[] content, - long expectedStartRange, - long expectedEndRange, - long expectedTotalBytes, - HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.PartialContent, response.StatusCode); - Assert.IsNotNull(content); - BlobTestUtils.LastModifiedHeader(response); - BlobTestUtils.ContentLengthHeader(response, content.Length); - BlobTestUtils.ETagHeader(response); - BlobTestUtils.RequestIdHeader(response); - BlobTestUtils.Contents(response, content); - BlobTestUtils.ContentRangeHeader(response, expectedStartRange, expectedEndRange, expectedTotalBytes); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - - response.Close(); - } - - public static HttpWebRequest PutBlockRequest(BlobContext context, string containerName, string blobName, string blockId, AccessCondition accessCondition) - { - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - HttpWebRequest request = null; - OperationContext opContext = new OperationContext(); - request = BlobHttpWebRequestFactory.PutBlock(uri, context.Timeout, blockId, accessCondition, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.ContentLanguageHeader(request, null); - BlobTestUtils.ContentMd5Header(request, null); - return request; - } - - public static void PutBlockResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, response.StatusDescription); - BlobTestUtils.ContentMd5Header(response); - BlobTestUtils.RequestIdHeader(response); - BlobTestUtils.ContentLengthHeader(response, -1); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - response.Close(); - } - - public static HttpWebRequest PutBlockListRequest(BlobContext context, string containerName, string blobName, BlobProperties blobProperties, AccessCondition accessCondition) - { - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - HttpWebRequest request = null; - OperationContext opContext = new OperationContext(); - request = BlobHttpWebRequestFactory.PutBlockList(uri, context.Timeout, blobProperties, accessCondition, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.ContentLanguageHeader(request, null); - BlobTestUtils.ContentMd5Header(request, null); - return request; - } - - public static void PutBlockListResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, response.StatusDescription); - BlobTestUtils.ContentMd5Header(response); - BlobTestUtils.RequestIdHeader(response); - BlobTestUtils.ContentLengthHeader(response, -1); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - response.Close(); - } - - /// - /// Generates and validates a request to acquire a lease. - /// - /// The blob context. - /// The container name. - /// The blob name. - /// The lease duration. - /// The proposed lease ID. - /// A web request for the operation. - public static HttpWebRequest AcquireLeaseRequest(BlobContext context, string containerName, string blobName, int leaseDuration, string proposedLeaseId, AccessCondition accessCondition) - { - HttpWebRequest request; - OperationContext opContext = new OperationContext(); - if (blobName != null) - { - // blob lease - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - request = BlobHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Acquire, - proposedLeaseId, - leaseDuration, - null /* break period */, - accessCondition, - opContext); - } - else - { - // container lease - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - request = ContainerHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Acquire, - proposedLeaseId, - leaseDuration, - null /* break period */, - accessCondition, - opContext); - } - Assert.IsNotNull(request); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.LeaseIdHeader(request, null); - BlobTestUtils.LeaseActionHeader(request, "acquire"); - BlobTestUtils.LeaseDurationHeader(request, leaseDuration.ToString()); - BlobTestUtils.ProposedLeaseIdHeader(request, proposedLeaseId); - BlobTestUtils.BreakPeriodHeader(request, null); - return request; - } - - /// - /// Validates a response to an acquire lease operation. - /// - /// The response to validate. - /// The expected lease ID. - /// The error status code to expect. - public static void AcquireLeaseResponse(HttpWebResponse response, string expectedLeaseId, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.Created, response.StatusCode, response.StatusDescription); - - if (expectedLeaseId != null) - { - BlobTestUtils.LeaseIdHeader(response, expectedLeaseId); - } - else - { - BlobTestUtils.LeaseIdHeader(response); - } - - BlobTestUtils.LeaseTimeHeader(response, null, null); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - /// - /// Generates and validates a request to renew a lease. - /// - /// The blob context. - /// The container name. - /// The blob name. - /// The lease ID. - /// A web request for the operation. - public static HttpWebRequest RenewLeaseRequest(BlobContext context, string containerName, string blobName, AccessCondition accessCondition) - { - HttpWebRequest request; - OperationContext opContext = new OperationContext(); - if (blobName != null) - { - // blob lease - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - request = BlobHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Renew, - null /* proposed lease ID */, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - else - { - // container lease - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - request = ContainerHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Renew, - null /* proposed lease ID */, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - Assert.IsNotNull(request); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId); - BlobTestUtils.LeaseActionHeader(request, "renew"); - BlobTestUtils.LeaseDurationHeader(request, null); - BlobTestUtils.ProposedLeaseIdHeader(request, null); - BlobTestUtils.BreakPeriodHeader(request, null); - return request; - } - - /// - /// Validates a response to a renew lease operation. - /// - /// The response to validate. - /// The expected lease ID. - /// The error status code to expect. - public static void RenewLeaseResponse(HttpWebResponse response, string expectedLeaseId, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - - if (expectedLeaseId != null) - { - BlobTestUtils.LeaseIdHeader(response, expectedLeaseId); - } - else - { - BlobTestUtils.LeaseIdHeader(response); - } - - BlobTestUtils.LeaseTimeHeader(response, null, null); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - /// - /// Generates and validates a request to change a lease. - /// - /// The blob context. - /// The container name. - /// The blob name. - /// The lease ID. - /// The proposed lease ID. - /// A web request for the operation. - public static HttpWebRequest ChangeLeaseRequest(BlobContext context, string containerName, string blobName, string proposedLeaseId, AccessCondition accessCondition) - { - HttpWebRequest request; - OperationContext opContext = new OperationContext(); - if (blobName != null) - { - // blob lease - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - request = BlobHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Change, - proposedLeaseId, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - else - { - // container lease - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - request = ContainerHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Change, - proposedLeaseId, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - Assert.IsNotNull(request); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId); - BlobTestUtils.LeaseActionHeader(request, "change"); - BlobTestUtils.LeaseDurationHeader(request, null); - BlobTestUtils.ProposedLeaseIdHeader(request, proposedLeaseId); - BlobTestUtils.BreakPeriodHeader(request, null); - return request; - } - - /// - /// Validates a response to a change lease operation. - /// - /// The response to validate. - /// The expected lease ID. - /// The error status code to expect. - public static void ChangeLeaseResponse(HttpWebResponse response, string expectedLeaseId, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - - if (expectedLeaseId != null) - { - BlobTestUtils.LeaseIdHeader(response, expectedLeaseId); - } - else - { - BlobTestUtils.LeaseIdHeader(response); - } - - BlobTestUtils.LeaseTimeHeader(response, null, null); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - /// - /// Generates and validates a request to release a lease. - /// - /// The blob context. - /// The container name. - /// The blob name. - /// The lease ID. - /// A web request for the operation. - public static HttpWebRequest ReleaseLeaseRequest(BlobContext context, string containerName, string blobName, AccessCondition accessCondition) - { - HttpWebRequest request; - OperationContext opContext = new OperationContext(); - if (blobName != null) - { - // blob lease - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - request = BlobHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Release, - null /* proposed lease ID */, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - else - { - // container lease - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - request = ContainerHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Release, - null /* proposed lease ID */, - null /* lease duration */, - null /* break period */, - accessCondition, - opContext); - } - Assert.IsNotNull(request); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.LeaseIdHeader(request, accessCondition == null ? null : accessCondition.LeaseId); - BlobTestUtils.LeaseActionHeader(request, "release"); - BlobTestUtils.LeaseDurationHeader(request, null); - BlobTestUtils.ProposedLeaseIdHeader(request, null); - BlobTestUtils.BreakPeriodHeader(request, null); - return request; - } - - /// - /// Validates a response to a release lease operation. - /// - /// The response to validate. - /// The error status code to expect. - public static void ReleaseLeaseResponse(HttpWebResponse response, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - BlobTestUtils.LeaseIdHeader(response, null); - BlobTestUtils.LeaseTimeHeader(response, null, null); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - /// - /// Generates and validates a request to break a lease. - /// - /// The blob context. - /// The container name. - /// The blob name. - /// The break period. - /// A web request for the operation. - public static HttpWebRequest BreakLeaseRequest(BlobContext context, string containerName, string blobName, int? breakPeriod, AccessCondition accessCondition) - { - HttpWebRequest request; - OperationContext opContext = new OperationContext(); - if (blobName != null) - { - // blob lease - Uri uri = BlobTests.ConstructPutUri(context.Address, containerName, blobName); - request = BlobHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Break, - null /* proposed lease ID */, - null /* lease duration */, - breakPeriod, - accessCondition, - opContext); - } - else - { - // container lease - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - request = ContainerHttpWebRequestFactory.Lease( - uri, - context.Timeout, - LeaseAction.Break, - null /* proposed lease ID */, - null /* lease duration */, - breakPeriod, - accessCondition, - opContext); - } - Assert.IsNotNull(request); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.VersionHeader(request, false); - BlobTestUtils.LeaseIdHeader(request, null); - BlobTestUtils.LeaseActionHeader(request, "break"); - BlobTestUtils.LeaseDurationHeader(request, null); - BlobTestUtils.ProposedLeaseIdHeader(request, null); - BlobTestUtils.BreakPeriodHeader(request, breakPeriod.HasValue ? breakPeriod.Value.ToString() : null); - return request; - } - - /// - /// Validates a response to a break lease operation. - /// - /// The response to validate. - /// The expected remaining lease time. - /// The error margin on the expected remaining lease time. - /// The error status code to expect. - public static void BreakLeaseResponse(HttpWebResponse response, int expectedLeaseTime, int errorMargin, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.Accepted, response.StatusCode, response.StatusDescription); - BlobTestUtils.LeaseIdHeader(response, null); - BlobTestUtils.LeaseTimeHeader(response, expectedLeaseTime, errorMargin); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - public static HttpWebRequest CreateContainerRequest(BlobContext context, string containerName) - { - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = ContainerHttpWebRequestFactory.Create(uri, context.Timeout, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("PUT", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static HttpWebRequest DeleteContainerRequest(BlobContext context, string containerName, AccessCondition accessCondition) - { - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = ContainerHttpWebRequestFactory.Delete(uri, context.Timeout, accessCondition, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("DELETE", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static HttpWebRequest DeleteBlobRequest(BlobContext context, string containerName, string blobName, AccessCondition accessCondition) - { - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName, blobName); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = BlobHttpWebRequestFactory.Delete(uri, context.Timeout, null /* snapshot */, DeleteSnapshotsOption.None, accessCondition, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("DELETE", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static HttpWebRequest ListBlobsRequest(BlobContext context, string containerName, BlobListingContext listingContext) - { - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = ContainerHttpWebRequestFactory.ListBlobs(uri, context.Timeout, listingContext, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("GET", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static void ListBlobsResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - BlobTestUtils.ContentTypeHeader(response, "application/xml"); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - public static HttpWebRequest ListContainersRequest(BlobContext context, ListingContext listingContext) - { - Uri uri = BlobClientTests.ConstructUri(context.Address); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = ContainerHttpWebRequestFactory.List(uri, context.Timeout, listingContext, ContainerListingDetails.Metadata, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("GET", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static void ListContainersResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - BlobTestUtils.ContentTypeHeader(response, "application/xml"); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - public static HttpWebRequest GetBlockListRequest(BlobContext context, string containerName, string blobName, BlockListingFilter typesOfBlocks, AccessCondition accessCondition) - { - Uri uri = BlobClientTests.ConstructUri(context.Address, containerName, blobName); - OperationContext opContext = new OperationContext(); - HttpWebRequest request = BlobHttpWebRequestFactory.GetBlockList(uri, context.Timeout, null /* snapshot */, typesOfBlocks, accessCondition, opContext); - Assert.IsNotNull(request); - Assert.IsNotNull(request.Method); - Assert.AreEqual("GET", request.Method); - BlobTestUtils.RangeHeader(request, null); - BlobTestUtils.LeaseIdHeader(request, null); - return request; - } - - public static void GetBlockListResponse(HttpWebResponse response, BlobContext context, HttpStatusCode? expectedError) - { - Assert.IsNotNull(response); - if (expectedError == null) - { - Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, response.StatusDescription); - BlobTestUtils.ContentTypeHeader(response, "application/xml"); - BlobTestUtils.RequestIdHeader(response); - } - else - { - Assert.AreEqual(expectedError, response.StatusCode, response.StatusDescription); - } - } - - public static Uri ConstructPutUri(string address, string containerName, string blobName) - { - return BlobTests.GenericUri(address, containerName, blobName); - } - - public static Uri ConstructGetUri(string address, string containerName, string blobName) - { - return BlobTests.GenericUri(address, containerName, blobName); - } - - static Uri GenericUri(string address, string containerName, string blobName) - { - Assert.IsNotNull(address); - Assert.IsNotNull(containerName); - Assert.IsNotNull(blobName); - - Uri uri = null; - try - { - uri = new Uri(String.Format("{0}/{1}/{2}", address, containerName, blobName)); - } - catch (Exception) - { - Assert.Fail("Cannot create URI with given arguments."); - } - return uri; - } - - public static void SignRequest(HttpWebRequest request, BlobContext context) - { - Assert.IsNotNull(request); - Assert.IsNotNull(context); - - OperationContext opContext = new OperationContext(); - SharedKeyAuthenticationHandler handler = new SharedKeyAuthenticationHandler( - SharedKeyCanonicalizer.Instance, - context.Credentials, - context.Account); - handler.SignRequest(request, opContext); - - BlobTestUtils.AuthorizationHeader(request, true, context.Account); - BlobTestUtils.DateHeader(request, true); - } - - public static bool ContainerNameValidator(string name) - { - Regex nameRegex = new Regex(@"^([a-z0-9]|((?<=[a-z0-9])-(?=[a-z0-9]))){3,63}$"); - return nameRegex.IsMatch(name); - } - - public static bool BlobNameValidator(string name) - { - Regex nameRegex = new Regex(@"^([0-9a-zA-Z\$\-_\.\+!\*'(),]|(%[0-9a-fA-F]{2})){1,}$"); - return nameRegex.IsMatch(name) && name.Length <= 1024; - } - - public static bool PutPropertiesValidator(BlobProperties properties) - { - if (properties.BlobType == BlobType.Unspecified) - { - return false; - } - - if ((properties.BlobType == BlobType.PageBlob) && - (properties.Length % 512 != 0) && - (properties.Length > 0)) - { - return false; - } - - return true; - } - - public static void AcquireAndReleaseLeaseTest(BlobContext context, string containerName, string blobName) - { - CloudStorageAccount account = new CloudStorageAccount(new StorageCredentials(context.Account, context.Key), false); - CloudBlobClient client = new CloudBlobClient(new Uri(context.Address), account.Credentials); - CloudBlobContainer container = client.GetContainerReference(containerName); - CloudBlockBlob blob = container.GetBlockBlobReference(blobName); - - BlobTestBase.UploadText(blob, "Text sent to cloud", Encoding.UTF8); - - // acquire a release on the blob and check LeaseStatus to be "locked" - OperationContext opContext = new OperationContext(); - HttpWebRequest blobRequest = BlobHttpWebRequestFactory.Lease( - blob.Uri, - context.Timeout, - LeaseAction.Acquire, - null /* proposed lease ID */, - 60 /* lease duration */, - null /* break period */, - null /* access condition */, - opContext); - BlobTests.SignRequest(blobRequest, context); - string leaseId = null; - using (HttpWebResponse response = (HttpWebResponse)blobRequest.GetResponse()) - { - leaseId = response.Headers["x-ms-lease-id"]; - Assert.AreEqual(response.StatusCode, HttpStatusCode.Created); - } - - blob.FetchAttributes(); - Assert.AreEqual(blob.Properties.LeaseStatus, LeaseStatus.Locked); - - // release the release on the blob and check LeaseStatus to be "unlocked" - opContext = new OperationContext(); - blobRequest = BlobHttpWebRequestFactory.Lease( - blob.Uri, - context.Timeout, - LeaseAction.Release, - null /* proposed lease ID */, - null /* lease duration */, - null /* break period */, - AccessCondition.GenerateLeaseCondition(leaseId), - opContext); - BlobTests.SignRequest(blobRequest, context); - using (HttpWebResponse response = (HttpWebResponse)blobRequest.GetResponse()) - { - Assert.AreEqual(response.StatusCode, HttpStatusCode.OK); - } - - blob.FetchAttributes(); - Assert.AreEqual(blob.Properties.LeaseStatus, LeaseStatus.Unlocked); - - blob.Delete(); - } - - public static bool LeaseIdValidator(AccessCondition accessCondition) - { - if (accessCondition != null && accessCondition.LeaseId != null) - { - Regex leaseIdRegex = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$"); - if (!leaseIdRegex.IsMatch(accessCondition.LeaseId)) - { - return false; - } - } - return true; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/SASTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/SASTests.cs deleted file mode 100644 index 17034a8b44d5c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Blob/SASTests.cs +++ /dev/null @@ -1,326 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class SASTests : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - this.testContainer.Create(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.Delete(); - this.testContainer = null; - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - private static void TestAccess(string sasToken, SharedAccessBlobPermissions permissions, CloudBlobContainer container, ICloudBlob blob) - { - StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ? - new StorageCredentials() : - new StorageCredentials(sasToken); - - if (container != null) - { - container = new CloudBlobContainer(credentials.TransformUri(container.Uri)); - if (blob.BlobType == BlobType.BlockBlob) - { - blob = container.GetBlockBlobReference(blob.Name); - } - else - { - blob = container.GetPageBlobReference(blob.Name); - } - } - else - { - if (blob.BlobType == BlobType.BlockBlob) - { - blob = new CloudBlockBlob(credentials.TransformUri(blob.Uri)); - } - else - { - blob = new CloudPageBlob(credentials.TransformUri(blob.Uri)); - } - } - - if (container != null) - { - if ((permissions & SharedAccessBlobPermissions.List) == SharedAccessBlobPermissions.List) - { - container.ListBlobs().ToArray(); - } - else - { - TestHelper.ExpectedException( - () => container.ListBlobs().ToArray(), - "List blobs while SAS does not allow for listing", - HttpStatusCode.NotFound); - } - } - - if ((permissions & SharedAccessBlobPermissions.Read) == SharedAccessBlobPermissions.Read) - { - blob.FetchAttributes(); - } - else - { - TestHelper.ExpectedException( - () => blob.FetchAttributes(), - "Fetch blob attributes while SAS does not allow for reading", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Write) == SharedAccessBlobPermissions.Write) - { - blob.SetMetadata(); - } - else - { - TestHelper.ExpectedException( - () => blob.SetMetadata(), - "Set blob metadata while SAS does not allow for writing", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Delete) == SharedAccessBlobPermissions.Delete) - { - blob.Delete(); - } - else - { - TestHelper.ExpectedException( - () => blob.Delete(), - "Delete blob while SAS does not allow for deleting", - HttpStatusCode.NotFound); - } - } - - private static void TestBlobSAS(ICloudBlob testBlob, SharedAccessBlobPermissions permissions) - { - UploadText(testBlob, "blob", Encoding.UTF8); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - - string sasToken = testBlob.GetSharedAccessSignature(policy); - SASTests.TestAccess(sasToken, permissions, null, testBlob); - } - - [TestMethod] - [Description("Test updateSASToken")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerUpdateSASToken() - { - // Create a policy with read/write access and get SAS. - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - UploadText(testBlockBlob, "blob", Encoding.UTF8); - TestAccess(sasToken, SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, this.testContainer, testBlockBlob); - - StorageCredentials creds = new StorageCredentials(sasToken); - - // Change the policy to only read and update SAS. - SharedAccessBlobPolicy policy2 = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read - }; - string sasToken2 = this.testContainer.GetSharedAccessSignature(policy2); - creds.UpdateSASToken(sasToken2); - - // Extra check to make sure that we have actually uopdated the SAS token. - CloudBlobContainer container = new CloudBlobContainer(this.testContainer.Uri, creds); - CloudBlockBlob blob = container.GetBlockBlobReference("blockblob2"); - - TestHelper.ExpectedException( - () => UploadText(blob, "blob", Encoding.UTF8), - "Writing to a blob while SAS does not allow for writing", - HttpStatusCode.NotFound); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - testPageBlob.Create(0); - TestAccess(sasToken2, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerSASCombinations() - { - for (int i = 1; i < 16; i++) - { - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob" + i); - UploadText(testBlockBlob, "blob", Encoding.UTF8); - SASTests.TestAccess(sasToken, permissions, this.testContainer, testBlockBlob); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob" + i); - UploadText(testPageBlob, "blob", Encoding.UTF8); - SASTests.TestAccess(sasToken, permissions, this.testContainer, testPageBlob); - } - } - - [TestMethod] - [Description("Test access on a public container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerPublicAccess() - { - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - UploadText(testBlockBlob, "blob", Encoding.UTF8); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - UploadText(testPageBlob, "blob", Encoding.UTF8); - - BlobContainerPermissions permissions = new BlobContainerPermissions(); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - this.testContainer.SetPermissions(permissions); - Thread.Sleep(35 * 1000); - SASTests.TestAccess(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - SASTests.TestAccess(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - - permissions.PublicAccess = BlobContainerPublicAccessType.Blob; - this.testContainer.SetPermissions(permissions); - Thread.Sleep(35 * 1000); - SASTests.TestAccess(null, SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - SASTests.TestAccess(null, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - } - - [TestMethod] - [Description("Test access on a public container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerPolicy() - { - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - UploadText(testBlockBlob, "blob", Encoding.UTF8); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - UploadText(testPageBlob, "blob", Encoding.UTF8); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read, - }; - - BlobContainerPermissions permissions = new BlobContainerPermissions(); - permissions.SharedAccessPolicies.Add("testpolicy", policy); - this.testContainer.SetPermissions(permissions); - Thread.Sleep(35 * 1000); - - string sasToken = testBlockBlob.GetSharedAccessSignature(null, "testpolicy"); - SASTests.TestAccess(sasToken, policy.Permissions, null, testBlockBlob); - - sasToken = testPageBlob.GetSharedAccessSignature(null, "testpolicy"); - SASTests.TestAccess(sasToken, policy.Permissions, null, testPageBlob); - - sasToken = this.testContainer.GetSharedAccessSignature(null, "testpolicy"); - SASTests.TestAccess(sasToken, policy.Permissions, this.testContainer, testBlockBlob); - SASTests.TestAccess(sasToken, policy.Permissions, this.testContainer, testPageBlob); - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlockBlobSASCombinations() - { - for (int i = 1; i < 8; i++) - { - CloudBlockBlob testBlob = this.testContainer.GetBlockBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - SASTests.TestBlobSAS(testBlob, permissions); - } - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudPageBlobSASCombinations() - { - for (int i = 1; i < 8; i++) - { - CloudPageBlob testBlob = this.testContainer.GetPageBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - SASTests.TestBlobSAS(testBlob, permissions); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/AsyncStreamCopierTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/AsyncStreamCopierTests.cs deleted file mode 100644 index 7285ebaa9f5a9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/AsyncStreamCopierTests.cs +++ /dev/null @@ -1,413 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Core.Executor; -using Microsoft.WindowsAzure.Storage.Core.Util; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - [TestClass] - public class AsyncStreamCopierTests : TestBase - { - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier and Count")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore)] - [TestCategory(TenantTypeCategory.DevFabric)] - [TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyMaxLengthTest() - { - // Boundary tests - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, true, 10, -1, true, 10, -1, null, true), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, false, 10, -1, true, 10, -1, null, true), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, true, 10, -1, false, 10, -1, null, true), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, false, 10, -1, false, 10, -1, null, true), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, true, 10, -1, true, 10, -1, null, false), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, false, 10, -1, true, 10, -1, null, false), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, true, 10, -1, false, 10, -1, null, false), - "Stream is longer than the allowed length."); - TestHelper.ExpectedException( - () => ValidateCopier((16 * 1024 * 1024), null, (16 * 1024 * 1024) - 1, false, 10, -1, false, 10, -1, null, false), - "Stream is longer than the allowed length."); - - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, true, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, false, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, true, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, false, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, true, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, false, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, true, 10, -1, false, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, 16 * 1024 * 1024, false, 10, -1, false, 10, -1, null, false); - - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, true, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, false, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, true, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, false, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, true, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, false, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, true, 10, -1, false, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, null, (16 * 1024 * 1024) + 1, false, 10, -1, false, 10, -1, null, false); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier and Count")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore)] - [TestCategory(TenantTypeCategory.DevFabric)] - [TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyCopyLengthTest() - { - // Copy half the stream - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, true, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, false, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, true, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, false, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, true, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, false, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, true, 10, -1, false, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 8 * 1024 * 1024, null, false, 10, -1, false, 10, -1, null, false); - - // Boundary tests - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, true, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, false, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, true, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, false, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, true, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, false, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, true, 10, -1, false, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) - 1, null, false, 10, -1, false, 10, -1, null, false); - - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, true, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, false, 10, -1, true, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, true, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, false, 10, -1, false, 10, -1, null, true); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, true, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, false, 10, -1, true, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, true, 10, -1, false, 10, -1, null, false); - ValidateCopier(16 * 1024 * 1024, 16 * 1024 * 1024, null, false, 10, -1, false, 10, -1, null, false); - - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, true, 10, -1, true, 10, -1, null, true), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, false, 10, -1, true, 10, -1, null, true), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, true, 10, -1, false, 10, -1, null, true), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, false, 10, -1, false, 10, -1, null, true), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, true, 10, -1, true, 10, -1, null, false), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, false, 10, -1, true, 10, -1, null, false), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, true, 10, -1, false, 10, -1, null, false), - "The given stream does not contain the requested number of bytes from its given position."); - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, (16 * 1024 * 1024) + 1, null, false, 10, -1, false, 10, -1, null, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncSameSpeedTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 10, -1, true, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncAsyncSameSpeedTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 10, -1, false, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncSyncSameSpeedTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 10, -1, true, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncSameSpeedTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 10, -1, false, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncSlowInputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 50, -1, true, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncAsyncSlowInputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 50, -1, false, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncSyncSlowInputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 50, -1, true, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncSlowInputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 50, -1, false, 10, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncSlowOutputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 10, -1, true, 50, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncAsyncSlowOutputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, true, 10, -1, false, 50, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncSyncSlowOutputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 10, -1, true, 50, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncSlowOutputTest() - { - ValidateCopier(16 * 1024 * 1024, null, null, false, 10, -1, false, 50, -1, null, true); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncFailInputTest() - { - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, true, 10, 5, true, 10, -1, null, true), - "Stream should have thrown an exception"); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncFailOutputTest() - { - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, true, 10, -1, true, 10, 5, null, true), - "Stream should have thrown an exception"); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncFailInputTest() - { - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, false, 10, 5, false, 10, -1, null, true), - "Stream should have thrown an exception"); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncFailOutputTest() - { - TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, false, 10, -1, false, 10, 5, null, true), - "Stream should have thrown an exception"); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopySyncSyncTimeoutTest() - { - StorageException e = TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, true, 2000, -1, true, 2000, -1, DateTime.Now.AddSeconds(5), true), - "Stream should have thrown an exception"); - - Assert.IsInstanceOfType(e.InnerException, typeof(TimeoutException)); - } - - [TestMethod] - [Description("Copy a stream to another using AsyncStreamCopier")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamCopyAsyncAsyncTimeoutTest() - { - StorageException e = TestHelper.ExpectedException( - () => ValidateCopier(16 * 1024 * 1024, null, null, false, 2000, -1, false, 2000, -1, DateTime.Now.AddSeconds(5), true), - "Stream should have thrown an exception"); - - Assert.IsInstanceOfType(e.InnerException, typeof(TimeoutException)); - } - - private static void ValidateCopier(int bufferLength, long? copyLength, long? maxLength, bool inputSync, int inputDelayInMs, int inputFailRequest, bool outputSync, int outputDelayInMs, int outputFailRequest, DateTime? copyTimeout, bool seekable) - { - byte[] buffer = GetRandomBuffer(bufferLength); - - // Finds ceiling of division operation - int expectedCallCount = - (int) - (copyLength.HasValue && buffer.Length > copyLength - ? (-1L + copyLength + Constants.DefaultBufferSize) / Constants.DefaultBufferSize - : (-1L + buffer.Length + Constants.DefaultBufferSize) / Constants.DefaultBufferSize); - - int totalDelayInMs = (expectedCallCount + 1) * inputDelayInMs + expectedCallCount * outputDelayInMs; - - DataValidationStream input = new DataValidationStream(buffer, inputSync, inputDelayInMs, inputFailRequest, seekable); - DataValidationStream output = new DataValidationStream(buffer, outputSync, outputDelayInMs, outputFailRequest, seekable); - RESTCommand cmdWithTimeout = new RESTCommand(new StorageCredentials(), null) { OperationExpiryTime = copyTimeout }; - ExecutionState state = new ExecutionState(cmdWithTimeout, null, null); - StreamDescriptor copyState = new StreamDescriptor(); - - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - input.WriteToAsync(output, copyLength, maxLength, false, state, copyState, _ => waitHandle.Set()); - Assert.IsTrue(waitHandle.WaitOne(totalDelayInMs + 10 * 1000)); - } - - if (inputFailRequest >= 0) - { - Assert.AreEqual(input.LastException, state.ExceptionRef); - Assert.AreEqual(inputFailRequest, input.ReadCallCount); - } - - if (outputFailRequest >= 0) - { - Assert.AreEqual(output.LastException, state.ExceptionRef); - Assert.AreEqual(outputFailRequest, output.WriteCallCount); - } - - if (state.ExceptionRef != null) - { - throw state.ExceptionRef; - } - - Assert.AreEqual(copyLength.HasValue ? copyLength : buffer.Length, copyState.Length); - Assert.AreEqual(copyLength.HasValue ? expectedCallCount : expectedCallCount + 1, input.ReadCallCount); - Assert.AreEqual(expectedCallCount, output.WriteCallCount); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/DataValidationStream.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/DataValidationStream.cs deleted file mode 100644 index 3720d3b774992..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/DataValidationStream.cs +++ /dev/null @@ -1,296 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - public class DataValidationStream : Stream - { - private byte[] streamContents; - private bool completeSynchronously; - private bool isSeekable; - private int delayInMs; - private int currentOffset; - private int allowedSuccessfulRequests; - - internal Exception LastException { get; private set; } - internal int ReadCallCount { get; private set; } - internal int WriteCallCount { get; private set; } - - public DataValidationStream(byte[] streamContents, bool completeSynchronously, int delayInMs, int allowedSuccessfulRequests, bool seekable) - { - this.streamContents = streamContents; - this.completeSynchronously = completeSynchronously; - this.delayInMs = delayInMs; - this.allowedSuccessfulRequests = allowedSuccessfulRequests; - this.currentOffset = 0; - this.LastException = null; - this.ReadCallCount = 0; - this.WriteCallCount = 0; - this.isSeekable = seekable; - } - - public override bool CanRead - { - get - { - return true; - } - } - - public override bool CanSeek - { - get - { - return this.isSeekable; - } - } - - public override bool CanWrite - { - get - { - return true; - } - } - - public override void Flush() - { - } - - public override long Length - { - get - { - if (!this.isSeekable) - { - throw new NotSupportedException(); - } - - return this.streamContents.Length; - } - } - - public override long Position - { - get - { - if (!this.isSeekable) - { - throw new NotSupportedException(); - } - - return this.currentOffset; - } - set - { - if (!this.isSeekable) - { - throw new NotSupportedException(); - } - - this.currentOffset = (int)value; - } - } - - public override int Read(byte[] buffer, int offset, int count) - { - this.FailRequestIfNeeded(); - - this.ReadCallCount++; - Thread.Sleep(this.delayInMs); - - count = Math.Min(count, this.streamContents.Length - this.currentOffset); - Buffer.BlockCopy(this.streamContents, this.currentOffset, buffer, offset, count); - - this.currentOffset += count; - return count; - } - - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - if (this.completeSynchronously) - { - result.UpdateCompletedSynchronously(this.completeSynchronously); - try - { - result.Result = this.Read(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - } - else - { - ThreadPool.QueueUserWorkItem(_ => - { - result.UpdateCompletedSynchronously(this.completeSynchronously); - try - { - result.Result = this.Read(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - }, - null); - } - - return result; - } - - public override int EndRead(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - return result.Result; - } - - public override long Seek(long offset, SeekOrigin origin) - { - if (!this.isSeekable) - { - throw new NotSupportedException(); - } - - return this.ForceSeek(offset, origin); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - this.FailRequestIfNeeded(); - - this.WriteCallCount++; - Thread.Sleep(this.delayInMs); - - for (int i = 0; i < count; i++) - { - if (this.streamContents[this.currentOffset + i] != buffer[offset + i]) - { - this.LastException = new InvalidDataException(string.Format("MISMATCH: Offset: {0} CompleteSync: {1} DelayInMs: {2}", - this.currentOffset + i, - this.completeSynchronously, - this.delayInMs)); - - throw this.LastException; - } - } - - this.currentOffset += count; - } - - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) - { - StorageAsyncResult result = new StorageAsyncResult(callback, state); - - if (this.completeSynchronously) - { - result.UpdateCompletedSynchronously(this.completeSynchronously); - try - { - this.Write(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - } - else - { - ThreadPool.QueueUserWorkItem(_ => - { - result.UpdateCompletedSynchronously(this.completeSynchronously); - try - { - this.Write(buffer, offset, count); - result.OnComplete(); - } - catch (Exception e) - { - result.OnComplete(e); - } - }, - null); - } - - return result; - } - - public override void EndWrite(IAsyncResult asyncResult) - { - StorageAsyncResult result = (StorageAsyncResult)asyncResult; - result.End(); - } - - private void FailRequestIfNeeded() - { - if (this.allowedSuccessfulRequests == 0) - { - this.LastException = new IOException(); - throw this.LastException; - } - else if (this.allowedSuccessfulRequests > 0) - { - this.allowedSuccessfulRequests--; - } - } - - public long ForceSeek(long offset, SeekOrigin origin) - { - long newOffset; - switch (origin) - { - case SeekOrigin.Begin: - newOffset = offset; - break; - - case SeekOrigin.Current: - newOffset = this.currentOffset + offset; - break; - - case SeekOrigin.End: - newOffset = this.Length + offset; - break; - - default: - CommonUtility.ArgumentOutOfRange("origin", origin); - throw new ArgumentOutOfRangeException(); - } - - CommonUtility.AssertInBounds("offset", newOffset, 0, this.Length); - - this.currentOffset = (int)newOffset; - - return this.currentOffset; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/LoggingTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/LoggingTests.cs deleted file mode 100644 index 2f8f2171de2b3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/LoggingTests.cs +++ /dev/null @@ -1,201 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Blob; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Diagnostics; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - [TestClass] - public class LoggingTests : TestBase - { - [TestInitialize] - public void TestInitialize() - { - TestLogListener.Restart(); - } - - [TestCleanup] - public void TestCleanup() - { - TestLogListener.Stop(); - } - - [TestMethod] - [Description("Do a set of operations and verify if everything is logged correctly")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void LoggingTest() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("logging" + Guid.NewGuid().ToString("N")); - try - { - OperationContext operationContext = new OperationContext(); - operationContext.LogLevel = LogLevel.Verbose; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - TestHelper.ExpectedException( - () => container.FetchAttributes(null, null, operationContext), - "Fetching a non-existent container's attributes should fail", - HttpStatusCode.NotFound); - Assert.AreEqual(1, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(2, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - container.CreateIfNotExists(null, operationContext); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - string lastLoggedRequestID = TestLogListener.LastRequestID; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - operationContext.LogLevel = LogLevel.Off; - container.DeleteIfExists(null, null, operationContext); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(lastLoggedRequestID, TestLogListener.LastRequestID); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Do a set of operations and verify if everything is logged correctly")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void LoggingTestAPM() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("logging" + Guid.NewGuid().ToString("N")); - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - OperationContext operationContext = new OperationContext(); - operationContext.LogLevel = LogLevel.Verbose; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - IAsyncResult result = container.BeginFetchAttributes(null, null, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => container.EndFetchAttributes(result), - "Fetching a non-existent container's attributes should fail", - HttpStatusCode.NotFound); - Assert.AreEqual(1, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(2, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - result = container.BeginCreateIfNotExists(null, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndCreateIfNotExists(result); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - string lastLoggedRequestID = TestLogListener.LastRequestID; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - operationContext.LogLevel = LogLevel.Off; - result = container.BeginDeleteIfExists(null, null, operationContext, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - container.EndDeleteIfExists(result); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(lastLoggedRequestID, TestLogListener.LastRequestID); - } - } - finally - { - container.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Do a set of operations and verify if everything is logged correctly")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void LoggingTestTask() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("logging" + Guid.NewGuid().ToString("N")); - try - { - OperationContext operationContext = new OperationContext(); - operationContext.LogLevel = LogLevel.Verbose; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - - TestHelper.ExpectedExceptionTask( - container.FetchAttributesAsync(null, null, operationContext), - "Fetching a non-existent container's attributes should fail", - HttpStatusCode.NotFound); - Assert.AreEqual(1, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(2, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - - container.CreateIfNotExistsAsync(null, operationContext).Wait(); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - string lastLoggedRequestID = TestLogListener.LastRequestID; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - operationContext.LogLevel = LogLevel.Off; - - container.DeleteIfExistsAsync(null, null, operationContext).Wait(); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(3, TestLogListener.WarningCount); - Assert.AreEqual(lastLoggedRequestID, TestLogListener.LastRequestID); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MD5WrapperTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MD5WrapperTests.cs deleted file mode 100644 index 9063accc0c084..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MD5WrapperTests.cs +++ /dev/null @@ -1,197 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Security.Cryptography; - -namespace Microsoft.WindowsAzure.Storage.Core.Util -{ - [TestClass()] - public class MD5WrapperTests - { - private byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; - - /// - /// FISMA MD5 and nativemd5 comparison test - /// - [TestMethod()] - public void MD5ComparisonTest() - { - CloudStorageAccount.UseV1MD5 = false; - - try - { - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - nativeHash.UpdateHash(data, 0, data.Length); - string nativeResult = nativeHash.ComputeHash(); - - MD5 hash = MD5.Create(); - hash.TransformBlock(data, 0, data.Length, null, 0); - hash.TransformFinalBlock(new byte[0], 0, 0); - byte[] bytes = hash.Hash; - string result = Convert.ToBase64String(bytes); - - Assert.AreEqual(nativeResult, result); - } - } - finally - { - CloudStorageAccount.UseV1MD5 = true; - } - } - - /// - /// Basic .net MD5 and nativemd5 comparison test - /// - [TestMethod()] - public void MD5V1ComparisonTest() - { - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - nativeHash.UpdateHash(data, 0, data.Length); - string nativeResult = nativeHash.ComputeHash(); - - MD5 hash = MD5.Create(); - hash.TransformBlock(data, 0, data.Length, null, 0); - hash.TransformFinalBlock(new byte[0], 0, 0); - byte[] bytes = hash.Hash; - string result = Convert.ToBase64String(bytes); - - Assert.AreEqual(nativeResult, result); - } - } - - /// - /// Test offset to the array - /// - [TestMethod()] - public void MD5SingleByteTest() - { - CloudStorageAccount.UseV1MD5 = false; - try - { - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - nativeHash.UpdateHash(data, 3, 2); - string nativeResult = nativeHash.ComputeHash(); - - MD5 hash = MD5.Create(); - hash.TransformBlock(data, 3, 2, null, 0); - hash.TransformFinalBlock(new byte[0], 0, 0); - byte[] bytes = hash.Hash; - string result = Convert.ToBase64String(bytes); - - Assert.AreEqual(nativeResult, result); - } - } - finally - { - CloudStorageAccount.UseV1MD5 = true; - } - } - - [TestMethod] - public void MD5EmptyArrayTest() - { - CloudStorageAccount.UseV1MD5 = false; - byte[] data = new byte[] { }; - try - { - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - nativeHash.UpdateHash(data, 0, data.Length); - string nativeResult = nativeHash.ComputeHash(); - - MD5 hash = MD5.Create(); - hash.ComputeHash(data, 0, data.Length); - byte[] varResult = hash.Hash; - string result = Convert.ToBase64String(varResult); - - Assert.AreEqual(nativeResult, result); - } - } - finally - { - CloudStorageAccount.UseV1MD5 = true; - } - } - - [TestMethod] - public void MD5BigDataTest() - { - CloudStorageAccount.UseV1MD5 = false; - byte[] data = new byte[10000]; - try - { - for (int i = 1; i < 10000; i++) - { - data[i] = 1; - } - - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - MD5 hash = MD5.Create(); - for (int i = 0; i < 999; i++) - { - int index = 10 * i; - nativeHash.UpdateHash(data, 0, 10); - hash.TransformBlock(data, 0, 10, null, 0); - } - string nativeResult = nativeHash.ComputeHash(); - - hash.TransformFinalBlock(new byte[0], 0, 0); - byte[] varResult = hash.Hash; - String result = Convert.ToBase64String(varResult); - - Assert.AreEqual(nativeResult, result); - } - } - finally - { - CloudStorageAccount.UseV1MD5 = true; - } - } - - [TestMethod] - public void MD5LastByteTest() - { - CloudStorageAccount.UseV1MD5 = false; - try - { - using (MD5Wrapper nativeHash = new MD5Wrapper()) - { - nativeHash.UpdateHash(data, 8, 1); - string nativeResult = nativeHash.ComputeHash(); - - - MD5 hash = MD5.Create(); - hash.ComputeHash(data, 8, 1); - byte[] varResult = hash.Hash; - string result = Convert.ToBase64String(varResult); - - Assert.AreEqual(nativeResult, result); - } - } - finally - { - CloudStorageAccount.UseV1MD5 = true; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MultiBufferMemoryStreamTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MultiBufferMemoryStreamTests.cs deleted file mode 100644 index 0e73423be3964..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/MultiBufferMemoryStreamTests.cs +++ /dev/null @@ -1,234 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Blob; -using Microsoft.WindowsAzure.Storage.Core.Executor; -using Microsoft.WindowsAzure.Storage.Core.Util; -using Microsoft.WindowsAzure.Storage.RetryPolicies; -using System; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - [TestClass] - public class MultiBufferMemoryStreamTests : TestBase - { - [TestMethod] - [Description("Copy between a MemoryStream and a MultiBufferMemoryStream")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void WriteToMultiBufferMemoryStreamTest() - { - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - - MultiBufferMemoryStream stream2 = new MultiBufferMemoryStream(null /* bufferManager */); - stream1.WriteToSync(stream2, null, null, false, true, tempExecutionState, null); - stream1.Seek(0, SeekOrigin.Begin); - stream2.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - MultiBufferMemoryStream stream3 = new MultiBufferMemoryStream(null /* bufferManager */); - TestHelper.ExpectedException( - () => stream2.FastCopyTo(stream3, DateTime.Now.AddMinutes(-1)), - "Past expiration time should immediately fail"); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - stream2.FastCopyTo(stream3, DateTime.Now.AddHours(1)); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream2, stream3); - - MultiBufferMemoryStream stream4 = new MultiBufferMemoryStream(null, 12345); - stream3.FastCopyTo(stream4, null); - stream3.Seek(0, SeekOrigin.Begin); - stream4.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream3, stream4); - - MemoryStream stream5 = new MemoryStream(); - stream4.WriteToSync(stream5, null, null, false, true, tempExecutionState, null); - stream4.Seek(0, SeekOrigin.Begin); - stream5.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream4, stream5); - - TestHelper.AssertStreamsAreEqual(stream1, stream5); - } - - [TestMethod] - [Description("Copy between a MemoryStream and a MultiBufferMemoryStream")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void WriteToMultiBufferMemoryStreamTestAPM() - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState state = new ExecutionState(cmd, new NoRetry(), new OperationContext()); - StreamDescriptor copyState = new StreamDescriptor(); - - MultiBufferMemoryStream stream2 = new MultiBufferMemoryStream(null /* bufferManager */); - stream1.WriteToAsync(stream2, null, null, false, state, copyState, _ => waitHandle.Set()); - waitHandle.WaitOne(); - if (state.ExceptionRef != null) - { - throw state.ExceptionRef; - } - - stream1.Seek(0, SeekOrigin.Begin); - stream2.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - MultiBufferMemoryStream stream3 = new MultiBufferMemoryStream(null /* bufferManager */); - IAsyncResult ar = stream2.BeginFastCopyTo(stream3, DateTime.Now.AddMinutes(-1), _ => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => stream3.EndFastCopyTo(ar), - "Past expiration time should immediately fail"); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - ar = stream2.BeginFastCopyTo(stream3, DateTime.Now.AddHours(1), _ => waitHandle.Set(), null); - waitHandle.WaitOne(); - stream2.EndFastCopyTo(ar); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream2, stream3); - - MultiBufferMemoryStream stream4 = new MultiBufferMemoryStream(null, 12345); - ar = stream3.BeginFastCopyTo(stream4, null, _ => waitHandle.Set(), null); - waitHandle.WaitOne(); - stream3.EndFastCopyTo(ar); - stream3.Seek(0, SeekOrigin.Begin); - stream4.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream3, stream4); - - state = new ExecutionState(cmd, new NoRetry(), new OperationContext()); - copyState = new StreamDescriptor(); - - MemoryStream stream5 = new MemoryStream(); - stream4.WriteToAsync(stream5, null, null, false, state, copyState, _ => waitHandle.Set()); - waitHandle.WaitOne(); - if (state.ExceptionRef != null) - { - throw state.ExceptionRef; - } - - stream4.Seek(0, SeekOrigin.Begin); - stream5.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream4, stream5); - - TestHelper.AssertStreamsAreEqual(stream1, stream5); - } - } - - [TestMethod] - [Description("Validate MultiBufferMemoryStream read functionality.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void MultiBufferMemoryStreamReadSeekSetLengthTest() - { - byte[] outBuffer = new byte[2 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(outBuffer.Length); - - using (MemoryStream memStream = new MemoryStream()) - { - memStream.Write(buffer, 0, buffer.Length); - using (MultiBufferMemoryStream multiBufferStream = new MultiBufferMemoryStream(null /* bufferManager */)) - { - multiBufferStream.Write(buffer, 0, buffer.Length); - multiBufferStream.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(memStream, multiBufferStream); - multiBufferStream.Read(outBuffer, 0, buffer.Length); - TestHelper.AssertBuffersAreEqual(buffer, outBuffer); - - multiBufferStream.Seek(-1, SeekOrigin.End); - Assert.AreEqual(buffer.Length - 1, multiBufferStream.Position); - - multiBufferStream.Seek(-1024, SeekOrigin.End); - memStream.Seek(-1024, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(multiBufferStream, memStream); - - multiBufferStream.SetLength(3 * 1024 * 1024); - memStream.SetLength(3 * 1024 * 1024); - multiBufferStream.Seek(0, SeekOrigin.Begin); - memStream.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(memStream, multiBufferStream); - } - } - } - - [TestMethod] - [Description("Validate MultiBufferMemoryStream read functionality.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void MultiBufferMemoryStreamReadSeekSetLengthTestAPM() - { - byte[] outBuffer = new byte[2 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(outBuffer.Length); - - using (MemoryStream memStream = new MemoryStream()) - { - memStream.Write(buffer, 0, buffer.Length); - using (MultiBufferMemoryStream multiBufferStream = new MultiBufferMemoryStream(null /* bufferManager */)) - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = multiBufferStream.BeginWrite(buffer, 0, buffer.Length, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - multiBufferStream.EndWrite(result); - multiBufferStream.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(memStream, multiBufferStream); - - result = multiBufferStream.BeginRead(outBuffer, 0, buffer.Length, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - multiBufferStream.EndRead(result); - TestHelper.AssertBuffersAreEqual(buffer, outBuffer); - - multiBufferStream.Seek(-1, SeekOrigin.End); - Assert.AreEqual(buffer.Length - 1, multiBufferStream.Position); - - multiBufferStream.Seek(-1024, SeekOrigin.End); - memStream.Seek(-1024, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(multiBufferStream, memStream); - - multiBufferStream.SetLength(3 * 1024 * 1024); - memStream.SetLength(3 * 1024 * 1024); - multiBufferStream.Seek(0, SeekOrigin.Begin); - memStream.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(memStream, multiBufferStream); - } - } - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/OperationContextUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/OperationContextUnitTests.cs deleted file mode 100644 index 3b9e7e23a4a3b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/OperationContextUnitTests.cs +++ /dev/null @@ -1,330 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Blob; -using Microsoft.WindowsAzure.Storage.Queue; -using Microsoft.WindowsAzure.Storage.Table; -using Microsoft.WindowsAzure.Test.Network; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Xml; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - /// - /// Summary description for OperationContextUnitTests - /// - [TestClass] - public class OperationContextUnitTests : TestBase - { - #region Locals + Ctors - public OperationContextUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - // [TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - // [TestCleanup()] - // public void MyTestCleanup() { } - // - #endregion - - [TestMethod] - [Description("Test last result")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestLastResult() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test"); - - DateTime start = DateTime.Now; - OperationContext opContext = new OperationContext(); - Assert.IsNull(opContext.LastResult); - container.Exists(null, opContext); - Assert.IsNotNull(opContext.LastResult); - Assert.IsNotNull(opContext.LastResult.RequestDate); - Assert.IsNotNull(opContext.LastResult.ServiceRequestID); - Assert.IsTrue(opContext.LastResult.StartTime >= start); - Assert.IsTrue(opContext.LastResult.EndTime <= DateTime.Now); - Assert.IsTrue(opContext.LastResult.HttpStatusCode > 0); - } - - [TestMethod] - [Description("Test client request id on blob request")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestClientRequestIDOnBlob() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - Action act = () => container.Exists(null, new OperationContext() { ClientRequestID = uniqueID }); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); - - act = () => container.EndExists(container.BeginExists(null, new OperationContext() { ClientRequestID = uniqueID }, null, null)); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); - -#if TASK - act = () => container.ExistsAsync(null, new OperationContext() { ClientRequestID = uniqueID }).Wait(); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); -#endif - } - - [TestMethod] - [Description("Test custom user headers on blob request")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestUserHeadersOnBlob() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - OperationContext ctx = new OperationContext(); - ctx.UserHeaders = new Dictionary(); - ctx.UserHeaders.Add("foo", "bar"); - - Action act = () => container.Exists(null, ctx); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); - - act = () => container.EndExists(container.BeginExists(null, ctx, null, null)); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); - -#if TASK - act = () => container.ExistsAsync(null, ctx).Wait(); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.BlobTraffic().IfHostNameContains(blobClient.Credentials.AccountName), act); -#endif - } - - [TestMethod] - [Description("Test client request id on queue request")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestClientRequestIDOnQueue() - { - CloudQueueClient qClient = GenerateCloudQueueClient(); - CloudQueue queue = qClient.GetQueueReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - Action act = () => queue.Exists(null, new OperationContext() { ClientRequestID = uniqueID }); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); - - act = () => queue.EndExists(queue.BeginExists(null, new OperationContext() { ClientRequestID = uniqueID }, null, null)); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); - -#if TASK - act = () => queue.ExistsAsync(null, new OperationContext() { ClientRequestID = uniqueID }).Wait(); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); -#endif - } - - [TestMethod] - [Description("Test custom user headers on queue request")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestUserHeadersOnQueue() - { - CloudQueueClient qClient = GenerateCloudQueueClient(); - CloudQueue queue = qClient.GetQueueReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - OperationContext ctx = new OperationContext(); - ctx.UserHeaders = new Dictionary(); - ctx.UserHeaders.Add("foo", "bar"); - - Action act = () => queue.Exists(null, ctx); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); - - act = () => queue.EndExists(queue.BeginExists(null, ctx, null, null)); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); - -#if TASK - act = () => queue.ExistsAsync(null, ctx).Wait(); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.QueueTraffic().IfHostNameContains(qClient.Credentials.AccountName), act); -#endif - } - - - [TestMethod] - [Description("Test client request id on table request")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestClientRequestIDOnTable() - { - CloudTableClient tClient = GenerateCloudTableClient(); - CloudTable table = tClient.GetTableReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - Action act = () => table.Exists(null, new OperationContext() { ClientRequestID = uniqueID }); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); - - act = () => table.EndExists(table.BeginExists(null, new OperationContext() { ClientRequestID = uniqueID }, null, null)); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); - -#if TASK - act = () => table.ExistsAsync(null, new OperationContext() { ClientRequestID = uniqueID }).Wait(); - - TestHelper.VerifyHeaderWasSent("x-ms-client-request-id", uniqueID, XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); -#endif - } - - [TestMethod] - [Description("Test custom user headers on table request")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestUserHeadersOnTable() - { - CloudTableClient tClient = GenerateCloudTableClient(); - CloudTable table = tClient.GetTableReference("test"); - - string uniqueID = Guid.NewGuid().ToString(); - - OperationContext ctx = new OperationContext(); - ctx.UserHeaders = new Dictionary(); - ctx.UserHeaders.Add("foo", "bar"); - - Action act = () => table.Exists(null, ctx); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); - - act = () => table.EndExists(table.BeginExists(null, ctx, null, null)); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); - -#if TASK - act = () => table.ExistsAsync(null, ctx).Wait(); - - TestHelper.VerifyHeaderWasSent(ctx.UserHeaders.Keys.First(), ctx.UserHeaders[ctx.UserHeaders.Keys.First()], XStoreSelectors.TableTraffic().IfHostNameContains(tClient.Credentials.AccountName), act); -#endif - } - - [TestMethod] - [Description("Test start / end time on OperationContext")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestStartEndTime() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test"); - - DateTime start = DateTime.Now; - OperationContext ctx = new OperationContext(); - container.Exists(null, ctx); - - Assert.IsNotNull(ctx.StartTime, "StartTime not set"); - Assert.IsTrue(ctx.StartTime >= start, "StartTime not set correctly"); - Assert.IsNotNull(ctx.EndTime, "EndTime not set"); - Assert.IsTrue(ctx.EndTime <= DateTime.Now, "EndTime not set correctly"); - } - - [TestMethod] - [Description("Test start / end time on OperationContext")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void OpContextTestStartEndTimeAPM() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test"); - - DateTime start = DateTime.Now; - OperationContext ctx = new OperationContext(); - container.EndCreateIfNotExists(container.BeginCreateIfNotExists(null, ctx, null, null)); - - Assert.IsNotNull(ctx.StartTime, "StartTime not set"); - Assert.IsTrue(ctx.StartTime >= start, "StartTime not set correctly"); - Assert.IsNotNull(ctx.EndTime, "EndTime not set"); - Assert.IsTrue(ctx.EndTime <= DateTime.Now, "EndTime not set correctly"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/RetryPoliciesTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/RetryPoliciesTests.cs deleted file mode 100644 index e555992d9415a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/RetryPoliciesTests.cs +++ /dev/null @@ -1,213 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.WindowsAzure.Storage.Blob; - using Microsoft.WindowsAzure.Storage.RetryPolicies; - using Microsoft.WindowsAzure.Storage.Table; - using System; - using System.Diagnostics; - using System.IO; - using System.Net; - using System.Threading; - - [TestClass] - public class RetryPoliciesTests : TableTestBase - { - [TestMethod] - [Description("Test to ensure that the time when we wait for a retry is cancellable")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void RetryDelayShouldBeCancellable() - { - using (ManualResetEvent responseWaitHandle = new ManualResetEvent(false), - callbackWaitHandle = new ManualResetEvent(false)) - { - BlobRequestOptions options = new BlobRequestOptions(); - options.RetryPolicy = new AlwaysRetry(TimeSpan.FromMinutes(1), 1); - OperationContext context = new OperationContext(); - context.ResponseReceived += (sender, e) => responseWaitHandle.Set(); - - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test" + DateTime.UtcNow.Ticks.ToString()); - ICancellableAsyncResult asyncResult = container.BeginFetchAttributes(null, options, context, - ar => - { - try - { - container.EndFetchAttributes(ar); - } - catch (Exception) - { - // This is expected, because we went for an invalid domain name. - } - - callbackWaitHandle.Set(); - }, - null); - - responseWaitHandle.WaitOne(); - Thread.Sleep(10 * 1000); - - Stopwatch stopwatch = Stopwatch.StartNew(); - - asyncResult.Cancel(); - callbackWaitHandle.WaitOne(); - - stopwatch.Stop(); - - Assert.IsTrue(stopwatch.Elapsed < TimeSpan.FromSeconds(10), stopwatch.Elapsed.ToString()); - Assert.AreEqual(1, context.RequestResults.Count); - } - } - - [TestMethod] - [Description("Test to ensure that the backoff time is set correctly in LinearRetry")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void VerifyLinearRetryBackOffTime() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(10), 4); - - OperationContext opContext = new OperationContext(); - TimeSpan retryInterval; - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(0, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(10), retryInterval); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(1, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(10), retryInterval); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(2, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(10), retryInterval); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(3, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(10), retryInterval); - - Assert.IsFalse(tableClient.RetryPolicy.ShouldRetry(4, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(10), retryInterval); - - tableClient.RetryPolicy = new LinearRetry(); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(0, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(30), retryInterval); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(1, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(30), retryInterval); - - Assert.IsTrue(tableClient.RetryPolicy.ShouldRetry(2, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(30), retryInterval); - - Assert.IsFalse(tableClient.RetryPolicy.ShouldRetry(3, 503, new Exception(), out retryInterval, opContext)); - Assert.AreEqual(TimeSpan.FromSeconds(30), retryInterval); - } - - [TestMethod] - [Description("Setting retry policy to null should not throw an exception")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void NullRetryPolicyTest() - { - CloudBlobClient blobClient = TestBase.GenerateCloudBlobClient(); - blobClient.RetryPolicy = null; - - CloudBlobContainer container = blobClient.GetContainerReference("test"); - container.Exists(); - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void RetryPolicyEnsure304IsNotRetried() - { - CloudBlobContainer container = BlobTestBase.GetRandomContainerReference(); - container.Create(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob"); - blob.UploadFromStream(new MemoryStream(new byte[50])); - - AccessCondition accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(blob.Properties.LastModified.Value.AddMinutes(10)); - OperationContext context = new OperationContext(); - - TestHelper.ExpectedException( - () => blob.FetchAttributes(accessCondition, new BlobRequestOptions() { RetryPolicy = new ExponentialRetry() }, context), - "FetchAttributes with invalid modified condition should return NotModified", - HttpStatusCode.NotModified); - - TestHelper.AssertNAttempts(context, 1); - - context = new OperationContext(); - - TestHelper.ExpectedException( - () => blob.FetchAttributes(accessCondition, new BlobRequestOptions() { RetryPolicy = new LinearRetry() }, context), - "FetchAttributes with invalid modified condition should return NotModified", - HttpStatusCode.NotModified); - - TestHelper.AssertNAttempts(context, 1); - } - finally - { - container.Delete(); - } - } - - [TestMethod] - [Description("Test to ensure that the backoff time does not overflow")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void VerifyBackoffTimeOverflow() - { - ExponentialRetry exponentialRetry = new ExponentialRetry(TimeSpan.FromSeconds(4), 100000); - VerifyBackoffTimeOverflow(exponentialRetry, 100000); - - LinearRetry linearRetry = new LinearRetry(TimeSpan.FromSeconds(4), 100000); - VerifyBackoffTimeOverflow(linearRetry, 100000); - } - - private void VerifyBackoffTimeOverflow(IRetryPolicy retryPolicy, int maxAttempts) - { - StorageException e = new StorageException(); - OperationContext context = new OperationContext(); - TimeSpan retryInterval; - TimeSpan previousRetryInterval = TimeSpan.FromMilliseconds(1); // larger than zero to ensure we never get zero back - - for (int i = 0; i < maxAttempts; i++) - { - Assert.IsTrue(retryPolicy.ShouldRetry(i, (int)HttpStatusCode.InternalServerError, e, out retryInterval, context), string.Format("Attempt: {0}", i)); - Assert.IsTrue(retryInterval >= previousRetryInterval, string.Format("Retry Interval: {0}, Previous Retry Interval: {1}, Attempt: {2}", retryInterval, previousRetryInterval, i)); - previousRetryInterval = retryInterval; - } - - Assert.IsFalse(retryPolicy.ShouldRetry(maxAttempts, (int)HttpStatusCode.InternalServerError, e, out retryInterval, context)); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TestLogListener.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TestLogListener.cs deleted file mode 100644 index f084435039ea2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TestLogListener.cs +++ /dev/null @@ -1,73 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Diagnostics; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - public partial class TestLogListener : TraceListener - { - private LogLevel currentLevel; - - public override void Write(string message) - { - string[] splittedMessage = message.Split(' ', ':'); - if (splittedMessage[0].Equals(Constants.LogSourceName)) - { - TraceEventType level; - if (!Enum.TryParse(splittedMessage[1], out level)) - { - throw new InvalidOperationException(); - } - - this.currentLevel = TestLogListener.MapLogLevel(level); - } - } - - public override void WriteLine(string message) - { - if (this.currentLevel != LogLevel.Off) - { - TestLogListener.ProcessMessage(this.currentLevel, message); - this.currentLevel = LogLevel.Off; - } - } - - private static LogLevel MapLogLevel(TraceEventType level) - { - switch (level) - { - case TraceEventType.Error: - return LogLevel.Error; - - case TraceEventType.Warning: - return LogLevel.Warning; - - case TraceEventType.Information: - return LogLevel.Informational; - - case TraceEventType.Verbose: - return LogLevel.Verbose; - - default: - throw new InvalidOperationException(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TplTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TplTests.cs deleted file mode 100644 index e71433e0dcaae..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/TplTests.cs +++ /dev/null @@ -1,142 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.IO; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using System.Threading.Tasks; - - [TestClass] - public class TplTests : TestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = BlobTestBase.GetRandomContainerReference(); - this.testContainer.CreateIfNotExists(); - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.DeleteIfExists(); - } - - [TestMethod] - [Description("Download multiple blobs asynchronously.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TplDownloadMultipleBlobsTest() - { - MemoryStream blobData1 = new MemoryStream(GetRandomBuffer(2 * 1024)); - MemoryStream blobData2 = new MemoryStream(GetRandomBuffer(2 * 1024)); - MemoryStream downloaded1 = new MemoryStream(); - MemoryStream downloaded2 = new MemoryStream(); - - CloudPageBlob blob1 = this.testContainer.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = this.testContainer.GetPageBlobReference("blob2"); - - - Task[] uploadTasks = new Task[] - { - blob1.UploadFromStreamAsync(blobData1), - blob2.UploadFromStreamAsync(blobData2) - }; - Task.WaitAll(uploadTasks); - - Task[] downloadTasks = new Task[] - { - blob1.DownloadToStreamAsync(downloaded1), - blob2.DownloadToStreamAsync(downloaded2) - }; - Task.WaitAll(downloadTasks); - - TestHelper.AssertStreamsAreEqual(blobData1, downloaded1); - TestHelper.AssertStreamsAreEqual(blobData2, downloaded2); - - blobData1.Dispose(); - blobData2.Dispose(); - downloaded1.Dispose(); - downloaded2.Dispose(); - } - - [TestMethod] - [Description("Start a blob upload and cancel the upload.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TplCancellationTest() - { - MemoryStream blobData = new MemoryStream(GetRandomBuffer(100 * 1024 * 1024)); - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - CancellationTokenSource tokenSource = new CancellationTokenSource(); - - // Test cancel before starting task - tokenSource.Cancel(); - - Task uploadTask = blob.UploadFromStreamAsync(blobData, tokenSource.Token); - - TestHelper.ExpectedExceptionTask(uploadTask, "Operation was canceled by user."); - - tokenSource.Dispose(); - - tokenSource = new CancellationTokenSource(); - Task uploadTask2 = blob.UploadFromStreamAsync(blobData, tokenSource.Token); - - Thread.Sleep(100); // Should take longer than 0.1 seconds to upload 100 MB - - // Test cancel after starting task - tokenSource.Cancel(); - - TestHelper.ExpectedExceptionTask(uploadTask2, "Operation was canceled by user."); - - tokenSource.Dispose(); - - // Test that task cannot be cancelled after it completes - MemoryStream blobData2 = new MemoryStream(GetRandomBuffer(2 * 1024)); - - tokenSource = new CancellationTokenSource(); - Task uploadTask3 = blob.UploadFromStreamAsync(blobData2, tokenSource.Token); - - while (!uploadTask3.IsCompleted) - { - Thread.Sleep(1000); - } - - tokenSource.Cancel(); - - // Should not throw OperationCanceledException because the task was canceled after it completed. - uploadTask3.Wait(); - - Assert.IsFalse(uploadTask3.IsCanceled); - Assert.IsTrue(uploadTask3.IsCompleted); - Assert.IsFalse(uploadTask3.IsFaulted); - Assert.AreEqual(uploadTask3.Status, TaskStatus.RanToCompletion); - - blobData.Dispose(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/WriteToSyncTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/WriteToSyncTests.cs deleted file mode 100644 index b24f7ae6c002d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Core/WriteToSyncTests.cs +++ /dev/null @@ -1,191 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using System; - using System.IO; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - - [TestClass] - public class WriteToSyncTests : TestBase - { - [TestMethod] - [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamWriteSyncTest() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - MemoryStream stream3 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test basic write - stream1.WriteToSync(stream2, null, null, true, false, tempExecutionState, null); - stream1.Position = 0; - stream1.WriteToSync(stream3, null, null, true, true, tempExecutionState, null); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - TestHelper.AssertStreamsAreEqual(stream1, stream3); - - stream2.Dispose(); - stream2 = new MemoryStream(); - - TestHelper.ExpectedException( - () => stream1.WriteToSync(stream2, 1024, 1024, true, false, tempExecutionState, null), - "Parameters copyLength and maxLength cannot be passed simultaneously."); - - stream1.Dispose(); - stream2.Dispose(); - stream3.Dispose(); - } - - [TestMethod] - [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamWriteSyncTestCopyLengthBoundary() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - MemoryStream stream3 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test write with exact number of bytes - stream1.WriteToSync(stream2, stream1.Length, null, true, false, tempExecutionState, null); - stream1.Position = 0; - stream1.WriteToSync(stream3, stream1.Length, null, true, true, tempExecutionState, null); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - TestHelper.AssertStreamsAreEqual(stream1, stream3); - - stream2.Dispose(); - stream2 = new MemoryStream(); - stream3.Dispose(); - stream3 = new MemoryStream(); - - // Test write with one less byte - stream1.WriteToSync(stream2, stream1.Length - 1, null, true, false, tempExecutionState, null); - stream1.Position = 0; - stream1.WriteToSync(stream3, stream1.Length - 1, null, true, true, tempExecutionState, null); - stream1.Position = 0; - - Assert.AreEqual(stream1.Length - 1, stream2.Length); - Assert.AreEqual(stream1.Length - 1, stream3.Length); - TestHelper.AssertStreamsAreEqualAtIndex(stream1, stream2, 0, 0, (int)stream1.Length - 1); - TestHelper.AssertStreamsAreEqualAtIndex(stream1, stream3, 0, 0, (int)stream1.Length - 1); - - stream2.Dispose(); - stream2 = new MemoryStream(); - stream3.Dispose(); - stream3 = new MemoryStream(); - - // Test with copyLength greater than length - TestHelper.ExpectedException( - () => stream1.WriteToSync(stream2, stream1.Length + 1, null, true, false, tempExecutionState, null), - "The given stream does not contain the requested number of bytes from its given position."); - stream1.Position = 0; - TestHelper.ExpectedException( - () => stream1.WriteToSync(stream3, stream1.Length + 1, null, true, true, tempExecutionState, null), - "The given stream does not contain the requested number of bytes from its given position."); - stream1.Position = 0; - - stream1.Dispose(); - stream2.Dispose(); - stream3.Dispose(); - } - - [TestMethod] - [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StreamWriteSyncTestMaxLengthBoundary() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - MemoryStream stream3 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test write with exact number of bytes - stream1.WriteToSync(stream2, null, stream1.Length, true, false, tempExecutionState, null); - stream1.Position = 0; - stream1.WriteToSync(stream3, null, stream1.Length, true, true, tempExecutionState, null); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - TestHelper.AssertStreamsAreEqual(stream1, stream3); - - stream2.Dispose(); - stream2 = new MemoryStream(); - stream3.Dispose(); - stream3 = new MemoryStream(); - - // Test write with one less byte - TestHelper.ExpectedException( - () => stream1.WriteToSync(stream2, null, stream1.Length - 1, true, false, tempExecutionState, null), - "Stream is longer than the allowed length."); - stream1.Position = 0; - TestHelper.ExpectedException( - () => stream1.WriteToSync(stream3, null, stream1.Length - 1, true, true, tempExecutionState, null), - "Stream is longer than the allowed length."); - stream1.Position = 0; - - stream2.Dispose(); - stream2 = new MemoryStream(); - stream3.Dispose(); - stream3 = new MemoryStream(); - - // Test with count greater than length - stream1.WriteToSync(stream2, null, stream1.Length + 1, true, false, tempExecutionState, null); - stream1.Position = 0; - stream1.WriteToSync(stream3, null, stream1.Length + 1, true, true, tempExecutionState, null); - stream1.Position = 0; - - // Entire stream should have been copied - TestHelper.AssertStreamsAreEqual(stream1, stream2); - TestHelper.AssertStreamsAreEqual(stream1, stream3); - - stream1.Dispose(); - stream2.Dispose(); - stream3.Dispose(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueClientTest.cs deleted file mode 100644 index e0258e738be83..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueClientTest.cs +++ /dev/null @@ -1,780 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Xml; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - /// - /// Summary description for CloudQueueClientTest - /// - [TestClass] - public class CloudQueueClientTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("A test checks basic function of CloudQueueClient.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint); - CloudQueueClient queueClient = new CloudQueueClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(queueClient.BaseUri.ToString().StartsWith(TestBase.TargetTenantConfig.QueueServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, queueClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, queueClient.AuthenticationScheme); - } - - [TestMethod] - [Description("A test checks basic function of CloudQueueClient.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientConstructorInvalidParam() - { - TestHelper.ExpectedException(() => new CloudQueueClient(null, TestBase.StorageCredentials), "Pass null into CloudQueueClient"); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesBasic() - { - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 30; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - CloudQueueClient client = GenerateCloudQueueClient(); - List emptyResults = client.ListQueues(prefix, QueueListingDetails.All, null, null).ToList(); - Assert.AreEqual(0, emptyResults.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).Create(); - } - - List results = client.ListQueues(prefix, QueueListingDetails.All, null, null).ToList(); - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmented() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - string queueName = prefix + i; - queueNames.Add(queueName); - client.GetQueueReference(queueName).Create(); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = client.ListQueuesSegmented(token); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - client.GetQueueReference(queue.Name).Delete(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefix() - { - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - - CloudQueueClient client = GenerateCloudQueueClient(); - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, QueueListingDetails.None, null, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).Create(); - } - - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, QueueListingDetails.None, 10, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefixOverload() - { - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - - CloudQueueClient client = GenerateCloudQueueClient(); - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, token); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).Create(); - } - - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, token); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("Verify GetSchema, WriteXml and ReadXml on QueueContinuationToken")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueContinuationTokenVerifyXml() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 30; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - client.GetQueueReference(prefix + i).Create(); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, QueueListingDetails.None, 5, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - token.WriteXml(writer); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new QueueContinuationToken(); - token.ReadXml(reader); - } - } - } - while (token != null); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("Verify GetSchema, WriteXml and ReadXml on QueueContinuationToken within another Xml")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueContinuationTokenVerifyXmlWithinXml() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 30; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - client.GetQueueReference(prefix + i).Create(); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = client.ListQueuesSegmented(prefix, QueueListingDetails.None, 5, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - writer.WriteStartElement("test1"); - writer.WriteStartElement("test2"); - token.WriteXml(writer); - writer.WriteEndElement(); - writer.WriteEndElement(); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new QueueContinuationToken(); - reader.ReadStartElement(); - reader.ReadStartElement(); - token.ReadXml(reader); - reader.ReadEndElement(); - reader.ReadEndElement(); - } - } - } - while (token != null); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("Test Create Queue with Shared Key Lite")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientCreateQueueSharedKeyLite() - { - CloudQueueClient queueClient = GenerateCloudQueueClient(); - queueClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string queueName = Guid.NewGuid().ToString("N"); - CloudQueue queue = queueClient.GetQueueReference(queueName); - queue.Create(); - - bool exists = queue.Exists(); - Assert.IsTrue(exists); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - string queueName = prefix + i; - queueNames.Add(queueName); - client.GetQueueReference(queueName).Create(); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - QueueContinuationToken token = null; - List results = new List(); - - do - { - IAsyncResult result = client.BeginListQueuesSegmented(token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueueResultSegment segment = client.EndListQueuesSegmented(result); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - client.GetQueueReference(queue.Name).Delete(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefixAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - QueueContinuationToken token = null; - List results = new List(); - do - { - IAsyncResult result = client.BeginListQueuesSegmented(prefix, QueueListingDetails.None, null, token, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueueResultSegment segment = client.EndListQueuesSegmented(result); - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).Create(); - } - - do - { - IAsyncResult result = client.BeginListQueuesSegmented(prefix, QueueListingDetails.None, 10, token, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueueResultSegment segment = client.EndListQueuesSegmented(result); - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefixAPMOverload() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - QueueContinuationToken token = null; - List results = new List(); - do - { - IAsyncResult result = client.BeginListQueuesSegmented(prefix, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueueResultSegment segment = client.EndListQueuesSegmented(result); - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).Create(); - } - - do - { - IAsyncResult result = client.BeginListQueuesSegmented(prefix, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueueResultSegment segment = client.EndListQueuesSegmented(result); - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.Delete(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - } - -#if TASK - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - string queueName = prefix + i; - queueNames.Add(queueName); - client.GetQueueReference(queueName).CreateAsync().Wait(); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = client.ListQueuesSegmentedAsync(token).Result; - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - client.GetQueueReference(queue.Name).DeleteAsync().Wait(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefixTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - do - { - QueueResultSegment segment = client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, null, token, null, null).Result; - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).CreateAsync().Wait(); - } - - do - { - QueueResultSegment segment = client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, 10, token, null, null).Result; - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.DeleteAsync().Wait(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientListQueuesSegmentedWithPrefixTaskOverload() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "dotnetqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - do - { - QueueResultSegment segment = client.ListQueuesSegmentedAsync(prefix, token).Result; - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - client.GetQueueReference(name).CreateAsync().Wait(); - } - - do - { - QueueResultSegment segment = client.ListQueuesSegmentedAsync(prefix, token).Result; - results.AddRange(segment.Results); - token = segment.ContinuationToken; - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - queue.DeleteAsync().Wait(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueMessageTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueMessageTest.cs deleted file mode 100644 index dbc52d95470ee..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueMessageTest.cs +++ /dev/null @@ -1,2332 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueMessageTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Test CloudQueueMessage constructor.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.CreateIfNotExists(); - - CloudQueueMessage message = new CloudQueueMessage(Guid.NewGuid().ToString()); - queue.AddMessage(message); - - CloudQueueMessage retrMessage = queue.GetMessage(); - string messageId = retrMessage.Id; - string popReceipt = retrMessage.PopReceipt; - - // Recreate the message using the messageId and popReceipt. - CloudQueueMessage newMessage = new CloudQueueMessage(messageId, popReceipt); - Assert.AreEqual(messageId, newMessage.Id); - Assert.AreEqual(popReceipt, newMessage.PopReceipt); - - queue.UpdateMessage(newMessage, TimeSpan.FromSeconds(30), MessageUpdateFields.Visibility); - CloudQueueMessage retrMessage2 = queue.GetMessage(); - Assert.AreEqual(null, retrMessage2); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test whether we can add message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessage(message); - - CloudQueueMessage receivedMessage1 = queue.GetMessage(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - - queue.UpdateMessage(receivedMessage1, TimeSpan.FromSeconds(1), MessageUpdateFields.Content | MessageUpdateFields.Visibility); - - queue.DeleteMessage(receivedMessage1); - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can add message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetMessageAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Add Message - IAsyncResult result = queue.BeginAddMessage(message, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Get message and test that it is correct - result = queue.BeginGetMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage receivedMessage1 = queue.EndGetMessage(result); - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - // Update Message - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - result = queue.BeginUpdateMessage( - receivedMessage1, - TimeSpan.FromSeconds(1), - MessageUpdateFields.Content | MessageUpdateFields.Visibility, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - queue.EndUpdateMessage(result); - - // Delete Message - result = queue.BeginDeleteMessage(receivedMessage1, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDeleteMessage(result); - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can add message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetMessageTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessageAsync(message).Wait(); - - CloudQueueMessage receivedMessage1 = queue.GetMessageAsync().Result; - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - - queue.UpdateMessageAsync(receivedMessage1, TimeSpan.FromSeconds(1), MessageUpdateFields.Content | MessageUpdateFields.Visibility).Wait(); - - queue.DeleteMessageAsync(receivedMessage1, null, null).Wait(); - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test whether we can add message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetByteMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - byte[] testData = new byte[20]; - CloudQueueMessage message = new CloudQueueMessage(testData); - queue.AddMessage(message); - - CloudQueueMessage receivedMessage1 = queue.GetMessage(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - TestHelper.AssertStreamsAreEqual(new MemoryStream(receivedMessage1.AsBytes), new MemoryStream(message.AsBytes)); - - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - - queue.UpdateMessage(receivedMessage1, TimeSpan.FromSeconds(1), MessageUpdateFields.Content | MessageUpdateFields.Visibility); - - queue.DeleteMessage(receivedMessage1); - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can add message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetByteMessageAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - byte[] testData = new byte[20]; - CloudQueueMessage message = new CloudQueueMessage(testData); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Add Message - IAsyncResult result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Test that message is correct - CloudQueueMessage receivedMessage1 = queue.GetMessage(); - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - TestHelper.AssertStreamsAreEqual(new MemoryStream(receivedMessage1.AsBytes), new MemoryStream(message.AsBytes)); - - // Update Message - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - result = queue.BeginUpdateMessage(receivedMessage1, - TimeSpan.FromSeconds(1), - MessageUpdateFields.Content | MessageUpdateFields.Visibility, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - queue.EndUpdateMessage(result); - - // Delete Message - result = queue.BeginDeleteMessage(receivedMessage1, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDeleteMessage(result); - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can add message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddGetByteMessageTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - byte[] testData = new byte[20]; - CloudQueueMessage message = new CloudQueueMessage(testData); - queue.AddMessageAsync(message).Wait(); - - CloudQueueMessage receivedMessage1 = queue.GetMessageAsync().Result; - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - TestHelper.AssertStreamsAreEqual(new MemoryStream(receivedMessage1.AsBytes), new MemoryStream(message.AsBytes)); - - receivedMessage1.SetMessageContent(Guid.NewGuid().ToString("N")); - - queue.UpdateMessageAsync( - receivedMessage1, - TimeSpan.FromSeconds(1), - MessageUpdateFields.Content | MessageUpdateFields.Visibility, - null, - new OperationContext()).Wait(); - - queue.DeleteMessageAsync(receivedMessage1, null, null).Wait(); - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test whether we can get message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - CloudQueueMessage emptyMessage = queue.GetMessage(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessage(message); - CloudQueueMessage receivedMessage1 = queue.GetMessage(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can get message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessageAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Get Empty Message - IAsyncResult result = queue.BeginGetMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage emptyMessage = queue.EndGetMessage(result); - Assert.IsNull(emptyMessage); - - // Create New Message - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - - // Add New Message - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Get New Message - result = queue.BeginGetMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage receivedMessage1 = queue.EndGetMessage(result); - - // Test Message - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - } - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can get messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessages() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - List emptyMessages = queue.GetMessages(messageCount).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessage(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = queue.GetMessages(messageCount).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can get messages with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessagesAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Get Messages - IAsyncResult result = queue.BeginGetMessages(messageCount, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - List emptyMessages = queue.EndGetMessages(result).ToList(); - - // No messages should be in queue - Assert.AreEqual(0, emptyMessages.Count); - - // Create messages to add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create a message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to Queue - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Add message to list to compare - messageContentList.Add(messageContent); - } - - // Get messages from queue - result = queue.BeginGetMessages(messageCount, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - List receivedMessages = queue.EndGetMessages(result).ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - } - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can get messages with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessagesWithTimeoutAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - // Create messages to add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create a message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to Queue - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Add message to list to compare - messageContentList.Add(messageContent); - } - - // Test 1 second timeout (minimum) - result = queue.BeginGetMessages( - messageCount, TimeSpan.FromSeconds(1), null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - - List receivedMessages = queue.EndGetMessages(result).ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - // Wait for the timeout to expire - Thread.Sleep(TimeSpan.FromSeconds(1)); - - // Test 7 day timeout (maximum) - result = queue.BeginGetMessages( - messageCount, TimeSpan.FromDays(7), null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - receivedMessages = queue.EndGetMessages(result).ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - } - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can get messages with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessagesNegativeAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result; - - // Create messages to add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create a message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to Queue - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Add message to list to compare - messageContentList.Add(messageContent); - } - - // Expect failure from zero visibility timeout - result = queue.BeginGetMessages(messageCount, TimeSpan.Zero, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => queue.EndGetMessages(result), - "Expect failure from zero visibility timeout"); - - // Expect failure from over 7 days visibility timeout - result = queue.BeginGetMessages( - messageCount, - TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1), - null, - null, - ar => waitHandle.Set(), - null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => queue.EndGetMessages(result), - "Expect failure from over 7 days visibility timeout"); - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can get messages with Task.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessagesTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - const int messageCount = 30; - - // Get Messages - List emptyMessages = queue.GetMessagesAsync(messageCount).Result.ToList(); - - // No messages should be in queue - Assert.AreEqual(0, emptyMessages.Count); - - // Create messages to add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create a message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to Queue - queue.AddMessageAsync(message).Wait(); - - // Add message to list to compare - messageContentList.Add(messageContent); - } - - // Get messages from queue - List receivedMessages = queue.GetMessagesAsync(messageCount).Result.ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - queue.DeleteAsync().Wait(); - } - - [TestMethod] - [Description("Test whether we can get messages with Task.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetMessagesWithTimeoutTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - const int messageCount = 30; - - // Create messages to add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create a message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to Queue - queue.AddMessageAsync(message).Wait(); - - // Add message to list to compare - messageContentList.Add(messageContent); - } - - // Test 1 second timeout (minimum) - List receivedMessages = queue.GetMessagesAsync(messageCount, TimeSpan.FromSeconds(1), null, null).Result.ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - // Wait for the timeout to expire - Thread.Sleep(TimeSpan.FromSeconds(1)); - - // Test 7 day timeout (maximum) - receivedMessages = queue.GetMessagesAsync(messageCount, TimeSpan.FromDays(7), null, null).Result.ToList(); - - // Test that messages are the same - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test the queue message within boundary.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageSmallBoundaryTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - CloudQueue queueRefWithoutBase64Encoding = client.GetQueueReference(name); - queueRefWithoutBase64Encoding.EncodeMessage = false; - - // boundary value 0 and 1 - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 0); - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 1); - - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 1024); - - queue.Delete(); - } - - [TestMethod] - [Description("Test the queue message within boundary.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageNormalBoundaryTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - CloudQueue queueRefWithoutBase64Encoding = client.GetQueueReference(name); - queueRefWithoutBase64Encoding.EncodeMessage = false; - - // a string with ascii chars of length 8*6144 will have Base64-encoded length 8*8192 (64kB) - // the following three test strings with length 8*6144-1, 8*6144, and 8*6144+1 - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 6144 - 1); - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 6144); - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 6144 + 1); - - // boundary value 8*8192-1, 8*8192, 8*8192+1 - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 8192 - 1); - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 8192); - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 8192 + 1); - - queue.Delete(); - } - - - [TestMethod] - [Description("Test the queue message within boundary.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageOverBoundaryTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - CloudQueue queueRefWithoutBase64Encoding = client.GetQueueReference(name); - queueRefWithoutBase64Encoding.EncodeMessage = false; - - // excessive message size - CloudQueueMessageBase64EncodingBoundaryTest(queue, queueRefWithoutBase64Encoding, 8 * 12288); - - queue.Delete(); - } - - /// - /// Perform a set of Queue message tests given the message length. - /// - private void CloudQueueMessageBase64EncodingBoundaryTest(CloudQueue queue, CloudQueue queueRefWithoutBase64Encoding, int messageLength) - { - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, true, false, false, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, true, false, true, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, true, true, false, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, true, true, true, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, false, false, false, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, false, false, true, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, false, true, false, messageLength); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, false, true, true, messageLength); - } - - /// - /// Perform a set of Queue message tests with different chars. - /// - private void QueueBase64EncodingTest(CloudQueue queue, CloudQueue queueRefWithoutBase64Encoding, bool useBase64Encoding, bool useString, bool hasInvalidCharacter, int messageLength) - { - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x0b, 'a'); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x0b, (char)0x21); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x0b, (char)0x7f); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x0b, (char)0xd7ff); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x0b, '<'); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0x19, '>'); - QueueBase64EncodingTest(queue, queueRefWithoutBase64Encoding, useBase64Encoding, useString, hasInvalidCharacter, messageLength, (char)0xfffe, '&'); - } - - /// - /// Perform a PUT and GET queue message test customized by a few parameters. - /// - private void QueueBase64EncodingTest(CloudQueue queue, CloudQueue queueRefWithoutBase64Encoding, bool useBase64Encoding, bool useString, bool hasInvalidCharacter, int messageLength, char invalidXmlChar, char validXmlChar) - { - queue.EncodeMessage = useBase64Encoding; - CloudQueueMessage originalMessage = null; - bool expectedExceptionThrown = false; - - if (!useString) - { - // hasInvalidCharacter is ignored - byte[] data = new byte[messageLength]; - Random random = new Random(); - random.NextBytes(data); - originalMessage = new CloudQueueMessage(data); - } - else - { - string message = CreateMessageString(messageLength, hasInvalidCharacter, invalidXmlChar, validXmlChar); - originalMessage = new CloudQueueMessage(message); - } - - // check invalid use case and length validation - if (!useString && !queue.EncodeMessage) - { - TestHelper.ExpectedException(() => { queue.AddMessage(originalMessage); }, "Binary data must be Base64 encoded"); - expectedExceptionThrown = true; - } - else - { - expectedExceptionThrown = QueueBase64EncodingTestVerifyLength(queue, originalMessage); - } - - if (!expectedExceptionThrown) - { - // check invalid XML characters validation - if (!queue.EncodeMessage && hasInvalidCharacter && messageLength > 0) - { - TestHelper.ExpectedException(() => { queue.AddMessage(originalMessage); }, "Invalid characters should throw if Base64 encoding is not used"); - expectedExceptionThrown = true; - } - else - { - // good to send messages - queue.AddMessage(originalMessage); - queue.AddMessage(originalMessage); - - if (useString) - { - QueueBase64EncodingTestDownloadMessageAndVerify(queue, queueRefWithoutBase64Encoding, originalMessage.AsString); - } - else - { - QueueBase64EncodingTestDownloadMessageAndVerify(queue, queueRefWithoutBase64Encoding, originalMessage.AsBytes); - } - } - } - } - - private static void QueueBase64EncodingTestDownloadMessageAndVerify(CloudQueue queue, CloudQueue queueRefWithoutBase64Encoding, string originalMessage) - { - // Assumption: 2 of the same messages have been added - // If the message was uploaded with Base64Encoding, this function will also retrieve the message without Base64 encoding. - CloudQueueMessage readBack = queue.GetMessage(); - Assert.AreEqual(originalMessage, readBack.AsString); - queue.DeleteMessage(readBack); - - if (queue.EncodeMessage) - { - CloudQueueMessage readBackWithoutBase64Encoding = queueRefWithoutBase64Encoding.GetMessage(); - string decodedMessage = Encoding.UTF8.GetString(Convert.FromBase64String(readBackWithoutBase64Encoding.AsString)); - Assert.AreEqual(originalMessage, decodedMessage); - queueRefWithoutBase64Encoding.DeleteMessage(readBackWithoutBase64Encoding); - } - else - { - readBack = queue.GetMessage(); - queue.DeleteMessage(readBack); - } - } - - private static bool QueueBase64EncodingTestVerifyLength(CloudQueue queue, CloudQueueMessage message) - { - const long MaxMessageSize = 64 * 1024; // 64kb - - if (queue.EncodeMessage && Convert.ToBase64String(message.AsBytes).Length > MaxMessageSize - || !queue.EncodeMessage && message.AsBytes.Length > MaxMessageSize) - { - TestHelper.ExpectedException(() => { queue.AddMessage(message); }, "Binary data must be Base64 encoded"); - return true; - } - - return false; - } - - private string CreateMessageString(int messageLength, bool hasInvalidCharacter, char invalidXmlChar, char validXmlChar) - { - char[] escapedChars = @"<>&".ToCharArray(); - - StringBuilder message = new StringBuilder(); - if (messageLength > 0) - { - if (hasInvalidCharacter) - { - message.Append(invalidXmlChar); - message.Append(CreateMessageString(messageLength - 1, false, invalidXmlChar, validXmlChar)); - } - else - { - // > and & will be encoded as > and & respectively and may result in RequestBodyTooLarge exception on server side - // so we don't add to many of these chars - if (messageLength <= 10 || !escapedChars.Contains(validXmlChar)) - { - message.Append(new string(validXmlChar, messageLength)); - } - else - { - message.Append(new string(validXmlChar, 10)); - message.Append(CreateMessageString(messageLength - 10, false, invalidXmlChar, 'a')); - } - } - } - - return message.ToString(); - } - - private static void QueueBase64EncodingTestDownloadMessageAndVerify(CloudQueue queue, CloudQueue queueRefWithoutBase64Encoding, byte[] originalData) - { - // Assumption: 2 of the same messages have been added - // If the message was uploaded with Base64Encoding, this function will also retrieve the message without Base64 encoding. - CloudQueueMessage readBack = queue.GetMessage(); - if (!CompareByteArray(originalData, readBack.AsBytes)) - { - string orignalData = PrintByteArray(originalData, "OriginalData"); - string returnedData = PrintByteArray(readBack.AsBytes, "ReturnedData"); - Assert.Fail("Data read back from server doesn't match the original data. \r\n{0}\r\n{1}", orignalData, returnedData); - } - - queue.DeleteMessage(readBack); - if (queue.EncodeMessage) - { - CloudQueueMessage readBackWithoutBase64Encoding = queueRefWithoutBase64Encoding.GetMessage(); - byte[] returnedDataWithoutBase64Encoding = Convert.FromBase64String(readBackWithoutBase64Encoding.AsString); - if (!CompareByteArray(originalData, returnedDataWithoutBase64Encoding)) - { - string orignalData = PrintByteArray(originalData, "OriginalData"); - string returnedData = PrintByteArray(returnedDataWithoutBase64Encoding, "ReturnedDataWithoutBase64Encoding"); - Assert.Fail("Data read back from server doesn't match the original data. \r\n{0}\r\n{1}", orignalData, returnedData); - } - - queueRefWithoutBase64Encoding.DeleteMessage(readBackWithoutBase64Encoding); - } - else - { - readBack = queue.GetMessage(); - queue.DeleteMessage(readBack); - } - } - - private static bool CompareByteArray(byte[] left, byte[] right) - { - bool isSame = true; - if (left.Length != right.Length) - { - isSame = false; - } - else - { - for (int i = 0; i < left.Length; i++) - { - if (left[i] != right[i]) - { - isSame = false; - break; - } - } - } - - return isSame; - } - - private static string PrintByteArray(byte[] data, string name) - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine(string.Format("Printing byte array: {0}, length: {1}", name, data.Length)); - foreach (byte b in data) - { - sb.Append(string.Format("{0:X2} ", b)); - } - - return sb.ToString(); - } - - [TestMethod] - [Description("Test whether process unicode message properly.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUnicodeMessages() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - queue.EncodeMessage = false; - - List messages = new List(); - messages.Add(@"Pour résoudre les problèmes, suivez les meilleures pratiques."); - messages.Add(@"Ваш логин Yahoo! дает доступ к таким мощным инструментам связи, как электронная почта, отправка мгновенных сообщений, функции безопасности, в частности, антивирусные средства и блокировщик всплывающей рекламы, и избранное, например, фото и музыка в сети — все бесплат"); - messages.Add(@"据新华社8月12日电 8月11日晚,舟曲境内再次出现强降雨天气,使特大山洪泥石流灾情雪上加霜。白龙江水在梨坝子村的交汇地带形成一个新的堰塞湖,水位比平时高出3米。甘肃省国土资源厅副厅长张国华当日22时许在新闻发布会上介绍,截至12日21时50分,舟曲堰塞湖堰塞体已消除,溃坝险情已消除,目前针对堰塞湖的主要工作是疏通河道。"); - messages.Add("ל כולם\", הדהים יעלון, ויישר קו עם העדות שמסר ראש הממשלה, בנימין נתניהו, לוועדת טירקל. לדבריו, אכן השרים דנו רק בהיבטים התקשורתיים של עצירת המשט: \"בשביעייה לא התקיים דיון על האלטרנטיבות. עסקנו בהיבטים "); - messages.Add(@"Prozent auf 0,5 Prozent. Im Vergleich zum Vorjahresquartal wuchs die deutsche Wirtschaft von Januar bis März um 2,1 Prozent. Auch das ist eine Korrektur nach oben, ursprünglich waren es hier 1,7 Prozent"); - messages.Add("\n\n\n\n Computer Parts\n \n Motherboard\n ASUS\n " + - "P3B-F\n 123.00\n \n \n Video Card\n ATI\n All-in-Wonder Pro\n 160.00\n \n \n Sound Card\n " + - "Creative Labs\n Sound Blaster Live\n 80.00\n \n \n inch Monitor\n LG Electronics\n 995E\n 290.00\n \n"); - - foreach (string msg in messages) - { - queue.AddMessage(new CloudQueueMessage(msg)); - - CloudQueueMessage readBack = queue.GetMessage(); - Assert.AreEqual(msg, readBack.AsString); - queue.DeleteMessage(readBack); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether process unicode message properly with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUnicodeMessagesAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - queue.EncodeMessage = false; - - List messages = new List(); - messages.Add(@"Pour résoudre les problèmes, suivez les meilleures pratiques."); - messages.Add(@"Ваш логин Yahoo! дает доступ к таким мощным инструментам связи, как электронная почта, отправка мгновенных сообщений, функции безопасности, в частности, антивирусные средства и блокировщик всплывающей рекламы, и избранное, например, фото и музыка в сети — все бесплат"); - messages.Add(@"据新华社8月12日电 8月11日晚,舟曲境内再次出现强降雨天气,使特大山洪泥石流灾情雪上加霜。白龙江水在梨坝子村的交汇地带形成一个新的堰塞湖,水位比平时高出3米。甘肃省国土资源厅副厅长张国华当日22时许在新闻发布会上介绍,截至12日21时50分,舟曲堰塞湖堰塞体已消除,溃坝险情已消除,目前针对堰塞湖的主要工作是疏通河道。"); - messages.Add("ל כולם\", הדהים יעלון, ויישר קו עם העדות שמסר ראש הממשלה, בנימין נתניהו, לוועדת טירקל. לדבריו, אכן השרים דנו רק בהיבטים התקשורתיים של עצירת המשט: \"בשביעייה לא התקיים דיון על האלטרנטיבות. עסקנו בהיבטים "); - messages.Add(@"Prozent auf 0,5 Prozent. Im Vergleich zum Vorjahresquartal wuchs die deutsche Wirtschaft von Januar bis März um 2,1 Prozent. Auch das ist eine Korrektur nach oben, ursprünglich waren es hier 1,7 Prozent"); - messages.Add("\n\n\n\n Computer Parts\n \n Motherboard\n ASUS\n " + - "P3B-F\n 123.00\n \n \n Video Card\n ATI\n All-in-Wonder Pro\n 160.00\n \n \n Sound Card\n " + - "Creative Labs\n Sound Blaster Live\n 80.00\n \n \n inch Monitor\n LG Electronics\n 995E\n 290.00\n \n"); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - foreach (string msg in messages) - { - // Add Message - IAsyncResult result = queue.BeginAddMessage(new CloudQueueMessage(msg), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Get Message - result = queue.BeginGetMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage readBack = queue.EndGetMessage(result); - - // Test Message - Assert.AreEqual(msg, readBack.AsString); - - // Delete Message - result = queue.BeginDeleteMessage(readBack, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDeleteMessage(result); - } - } - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can peek message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - CloudQueueMessage emptyMessage = queue.PeekMessage(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessage(message); - CloudQueueMessage receivedMessage1 = queue.PeekMessage(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can peek message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessageAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Peek Message - IAsyncResult result = queue.BeginPeekMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage emptyMessage = queue.EndPeekMessage(result); - - // Test that no message exists - Assert.IsNull(emptyMessage); - - // Create message and add - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Peek Message - result = queue.BeginPeekMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage receivedMessage1 = queue.EndPeekMessage(result); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - result = queue.BeginPeekMessage(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - receivedMessage1 = queue.EndPeekMessage(result); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can peek message with Task.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessageTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - CloudQueueMessage emptyMessage = queue.PeekMessageAsync().Result; - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessageAsync(message).Wait(); - CloudQueueMessage receivedMessage1 = queue.PeekMessageAsync(null, new OperationContext()).Result; - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test whether we can peek messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessages() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - List emptyMessages = queue.PeekMessages(messageCount).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessage(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = queue.PeekMessages(messageCount).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can peek messages with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessagesAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - const int messageCount = 30; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Peek messages - IAsyncResult result = queue.BeginPeekMessages(messageCount, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - List emptyMessages = queue.EndPeekMessages(result).ToList(); - - // Check that no messages exist - Assert.AreEqual(0, emptyMessages.Count); - - // Create message and add to queue - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - // Create message - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - - // Add message to queue - result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Also add to list to compare - messageContentList.Add(messageContent); - } - - // Peek messages - result = queue.BeginPeekMessages(messageCount, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - List receivedMessages = queue.EndPeekMessages(result).ToList(); - - // Test peeked messages - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - // Peek messages - QueueRequestOptions options = QueueRequestOptions.ApplyDefaults(new QueueRequestOptions(), client); - result = queue.BeginPeekMessages(messageCount, options, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - receivedMessages = queue.EndPeekMessages(result).ToList(); - - // Test peeked messages - Assert.AreEqual(messageCount, receivedMessages.Count); - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can peek messages with Task.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueuePeekMessagesTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - const int messageCount = 30; - - List emptyMessages = queue.PeekMessagesAsync(messageCount).Result.ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessageAsync(message).Wait(); - messageContentList.Add(messageContent); - } - - List receivedMessages = queue.PeekMessagesAsync(messageCount, null, new OperationContext()).Result.ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test whether we can clear message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearMessage() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessage(message); - CloudQueueMessage receivedMessage1 = queue.PeekMessage(); - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - queue.Clear(); - Assert.IsNull(queue.PeekMessage()); - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can clear message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearMessageAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - // Create Message - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - - // Add message to queue - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Add message - IAsyncResult result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Peek message - result = queue.BeginPeekMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage receivedMessage1 = queue.EndPeekMessage(result); - - // Test message - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - // Clear queue - result = queue.BeginClear(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndClear(result); - - // Test clear result - Assert.IsNull(queue.PeekMessage()); - } - queue.Delete(); - } - - [TestMethod] - [Description("Test whether we can clear message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearMessageFullParameterAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - // Create Message - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - - // Add message to queue - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - // Add message - IAsyncResult result = queue.BeginAddMessage(message, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Peek message - result = queue.BeginPeekMessage(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - CloudQueueMessage receivedMessage1 = queue.EndPeekMessage(result); - - // Test message - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - // Clear queue - result = queue.BeginClear(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndClear(result); - - // Test clear result - Assert.IsNull(queue.PeekMessage()); - } - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test whether we can clear message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearMessageTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - queue.AddMessageAsync(message).Wait(); - CloudQueueMessage receivedMessage1 = queue.PeekMessageAsync().Result; - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - queue.ClearAsync().Wait(); - Assert.IsNull(queue.PeekMessage()); - queue.DeleteAsync().Wait(); - } - - [TestMethod] - [Description("Test whether we can clear message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearMessageFullParameterTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - // Create Message - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - - // Add message - queue.AddMessageAsync(message).Wait(); - - // Peek message - CloudQueueMessage receivedMessage1 = queue.PeekMessageAsync().Result; - - // Test message - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - // Clear queue - queue.ClearAsync(null, new OperationContext()).Wait(); - - // Test clear result - Assert.IsNull(queue.PeekMessageAsync().Result); - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test when message is null.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageNull() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - queue.AddMessage(new CloudQueueMessage(Encoding.UTF8.GetBytes(""))); - CloudQueueMessage message = queue.GetMessage(); - Assert.IsNotNull(message); - Assert.IsNotNull(message.Id); - Assert.IsTrue(message.ExpirationTime.Value.Subtract(TimeSpan.FromMinutes(2)) > DateTime.UtcNow); - Assert.IsNotNull(message.AsString); - Assert.IsNotNull(message.InsertionTime.Value < DateTime.UtcNow); - Assert.IsNotNull(message.PopReceipt); - Assert.IsTrue(message.NextVisibleTime.Value.Add(TimeSpan.FromMinutes(2)) > DateTime.UtcNow); - - queue.Delete(); - } - - [TestMethod] - [Description("Test when message is null with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageNullAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - // Add blank message - IAsyncResult result = queue.BeginAddMessage(new CloudQueueMessage(Encoding.UTF8.GetBytes("")), - ar => waitHandler.Set(), - null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - // Get message - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - CloudQueueMessage message = queue.EndGetMessage(result); - - Assert.IsNotNull(message); - Assert.IsNotNull(message.Id); - Assert.IsTrue(message.ExpirationTime.Value.Subtract(TimeSpan.FromMinutes(2)) > DateTime.UtcNow); - Assert.IsNotNull(message.AsString); - Assert.IsNotNull(message.InsertionTime.Value < DateTime.UtcNow); - Assert.IsNotNull(message.PopReceipt); - Assert.IsTrue(message.NextVisibleTime.Value.Add(TimeSpan.FromMinutes(2)) > DateTime.UtcNow); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test add message with full parameter.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddMessageFullParameter() - { - CloudQueueMessage futureMessage = new CloudQueueMessage("This message is for the future."); - CloudQueueMessage presentMessage = new CloudQueueMessage("This message is for the present."); - - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - queue.AddMessage(futureMessage, null, TimeSpan.FromDays(2)); - - // We should not be able to see the future message yet. - CloudQueueMessage retrievedMessage = queue.GetMessage(); - Assert.IsNull(retrievedMessage); - - queue.AddMessage(presentMessage, null, TimeSpan.Zero); - - // We should be able to see the present message. - retrievedMessage = queue.GetMessage(); - Assert.IsNotNull(retrievedMessage); - Assert.AreEqual(presentMessage.AsString, retrievedMessage.AsString); - - TestHelper.ExpectedException( - () => queue.AddMessage(futureMessage, TimeSpan.FromDays(1), TimeSpan.FromDays(2)), - "Using a visibility timeout longer than the time to live should fail"); - - TestHelper.ExpectedException( - () => queue.AddMessage(futureMessage, null, TimeSpan.FromDays(8)), - "Using a visibility longer than the maximum time to live should fail"); - - TestHelper.ExpectedException( - () => queue.AddMessage(futureMessage, null, TimeSpan.FromMinutes(-1)), - "Using a negative visibility should fail"); - - queue.Delete(); - } - - [TestMethod] - [Description("Test add message with full parameter and APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddMessageFullParameterAPM() - { - CloudQueueMessage futureMessage = new CloudQueueMessage("This message is for the future."); - CloudQueueMessage presentMessage = new CloudQueueMessage("This message is for the present."); - - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - // Add Message - IAsyncResult result = queue.BeginAddMessage( - futureMessage, null, TimeSpan.FromDays(2), null, null, ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - // We should not be able to see the future message yet. - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - CloudQueueMessage retrievedMessage = queue.EndGetMessage(result); - - // Test message for null - Assert.IsNull(retrievedMessage); - - // Add Message - result = queue.BeginAddMessage( - presentMessage, null, TimeSpan.Zero, null, null, ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - // We should be able to see the present message. - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - retrievedMessage = queue.EndGetMessage(result); - - Assert.IsNotNull(retrievedMessage); - Assert.AreEqual(presentMessage.AsString, retrievedMessage.AsString); - - TestHelper.ExpectedException( - () => - queue.BeginAddMessage( - futureMessage, - TimeSpan.FromDays(1), - TimeSpan.FromDays(2), - null, - null, - ar => waitHandler.Set(), - null), - "Using a visibility timeout longer than the time to live should fail"); - - TestHelper.ExpectedException( - () => - queue.BeginAddMessage( - futureMessage, null, TimeSpan.FromDays(8), null, null, ar => waitHandler.Set(), null), - "Using a visibility longer than the maximum time to live should fail"); - - TestHelper.ExpectedException( - () => - queue.BeginAddMessage( - futureMessage, null, TimeSpan.FromMinutes(-1), null, null, ar => waitHandler.Set(), null), - "Using a negative visibility should fail"); - } - - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test add message with full parameter.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueAddMessageFullParameterTask() - { - CloudQueueMessage futureMessage = new CloudQueueMessage("This message is for the future."); - CloudQueueMessage presentMessage = new CloudQueueMessage("This message is for the present."); - - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - queue.AddMessageAsync(futureMessage, null, TimeSpan.FromDays(2), null, null).Wait(); - - // We should not be able to see the future message yet. - CloudQueueMessage retrievedMessage = queue.GetMessageAsync().Result; - Assert.IsNull(retrievedMessage); - - queue.AddMessageAsync(presentMessage, null, TimeSpan.Zero, null, null).Wait(); - - // We should be able to see the present message. - retrievedMessage = queue.GetMessageAsync().Result; - Assert.IsNotNull(retrievedMessage); - Assert.AreEqual(presentMessage.AsString, retrievedMessage.AsString); - - TestHelper.ExpectedException( - () => queue.AddMessageAsync(futureMessage, TimeSpan.FromDays(1), TimeSpan.FromDays(2), null, null), - "Using a visibility timeout longer than the time to live should fail"); - - TestHelper.ExpectedException( - () => queue.AddMessageAsync(futureMessage, null, TimeSpan.FromDays(8), null, null), - "Using a visibility longer than the maximum time to live should fail"); - - TestHelper.ExpectedException( - () => queue.AddMessageAsync(futureMessage, null, TimeSpan.FromMinutes(-1), null, null), - "Using a negative visibility should fail"); - - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Test add large message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageQueueAddLargeMessage() - { - long maxStringLength = CloudQueueMessage.MaxMessageSize; - long maxByteArrayLength = CloudQueueMessage.MaxMessageSize * 3 / 4; - - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - { - char[] longMessageChars = new char[maxStringLength]; - for (long i = 0; i < longMessageChars.LongLength; i++) - { - longMessageChars[i] = (char)('A' + (i % 26)); - } - - CloudQueueMessage longMessageFromString = new CloudQueueMessage(new string(longMessageChars)); - - // Do not encode the message. This allows a maximally-sized string to be used. - queue.EncodeMessage = false; - - // The following call should succeed. - queue.AddMessage(longMessageFromString); - - CloudQueueMessage retrievedMessage = queue.GetMessage(); - Assert.AreEqual(longMessageFromString.AsString, retrievedMessage.AsString); - } - - { - byte[] longMessageBytes = new byte[maxByteArrayLength]; - for (long i = 0; i < longMessageBytes.LongLength; i++) - { - longMessageBytes[i] = (byte)i; - } - - CloudQueueMessage longMessageFromByteArray = new CloudQueueMessage(longMessageBytes); - - // The following call should throw an exception because byte array messages must be base 64 encoded. - queue.EncodeMessage = false; - - TestHelper.ExpectedException( - () => queue.AddMessage(longMessageFromByteArray), - "AddMessage should throw an exception because byte array messages must be base 64 encoded"); - - // Encode the message in base 64. This is the only way to use byte arrays in a message. - queue.EncodeMessage = true; - - // The following call should succeed. - queue.AddMessage(longMessageFromByteArray); - - CloudQueueMessage retrievedMessage = queue.GetMessage(); - byte[] expectedBytes = longMessageFromByteArray.AsBytes; - byte[] foundBytes = retrievedMessage.AsBytes; - - Assert.AreEqual(expectedBytes.Length, foundBytes.Length); - - for (int i = 0; i < expectedBytes.Length; i++) - { - Assert.AreEqual(expectedBytes[i], foundBytes[i]); - } - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test add large message with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageQueueAddLargeMessageAPM() - { - long maxStringLength = CloudQueueMessage.MaxMessageSize; - long maxByteArrayLength = CloudQueueMessage.MaxMessageSize * 3 / 4; - - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - { - char[] longMessageChars = new char[maxStringLength]; - for (long i = 0; i < longMessageChars.LongLength; i++) - { - longMessageChars[i] = (char)('A' + (i % 26)); - } - - CloudQueueMessage longMessageFromString = new CloudQueueMessage(new string(longMessageChars)); - - // Do not encode the message. This allows a maximally-sized string to be used. - queue.EncodeMessage = false; - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - // The following call should succeed. - // Add Message - IAsyncResult result = queue.BeginAddMessage(longMessageFromString, ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - // Get Message - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - CloudQueueMessage retrievedMessage = queue.EndGetMessage(result); - - // Test message - Assert.AreEqual(longMessageFromString.AsString, retrievedMessage.AsString); - } - } - - { - byte[] longMessageBytes = new byte[maxByteArrayLength]; - for (long i = 0; i < longMessageBytes.LongLength; i++) - { - longMessageBytes[i] = (byte)i; - } - - CloudQueueMessage longMessageFromByteArray = new CloudQueueMessage(longMessageBytes); - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - // The following call should throw an exception because byte array messages must be base 64 encoded. - queue.EncodeMessage = false; - - TestHelper.ExpectedException( - () => queue.BeginAddMessage(longMessageFromByteArray, ar => waitHandler.Set(), null), - "BeginAddMessage should throw an exception because byte array messages must be base 64 encoded"); - - - // Encode the message in base 64. This is the only way to use byte arrays in a message. - queue.EncodeMessage = true; - - // The following call to BeginAddMessage should succeed. - IAsyncResult result = queue.BeginAddMessage(longMessageFromByteArray, ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - // Get Message - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - CloudQueueMessage retrievedMessage = queue.EndGetMessage(result); - - byte[] expectedBytes = longMessageFromByteArray.AsBytes; - byte[] foundBytes = retrievedMessage.AsBytes; - - Assert.AreEqual(expectedBytes.Length, foundBytes.Length); - - for (int i = 0; i < expectedBytes.Length; i++) - { - Assert.AreEqual(expectedBytes[i], foundBytes[i]); - } - } - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test update message with full parameters.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUpdateMessageFullParameter() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - queue.AddMessage(new CloudQueueMessage("message in queue")); - CloudQueueMessage messageFromQueue = queue.GetMessage(TimeSpan.FromDays(1)); - DateTimeOffset nextVisibleTime = messageFromQueue.NextVisibleTime.Value; - - // Modify the message contents client-side - messageFromQueue.SetMessageContent("new message content!"); - - // Increase the message's visibility timeout. - queue.UpdateMessage(messageFromQueue, TimeSpan.FromDays(2), MessageUpdateFields.Visibility); - - // The extra visibility time we get should be 1 day + small delta server time. - Assert.IsTrue(messageFromQueue.NextVisibleTime - nextVisibleTime >= TimeSpan.FromDays(1)); - - // Decrease the message's visibility timeout. - queue.UpdateMessage(messageFromQueue, TimeSpan.FromDays(1), MessageUpdateFields.Visibility); - - // Now the extra time equals a small delta server time. - Assert.IsTrue(messageFromQueue.NextVisibleTime - nextVisibleTime < TimeSpan.FromHours(1)); - - // Update the message's visibility and content. - queue.UpdateMessage(messageFromQueue, TimeSpan.FromSeconds(1), MessageUpdateFields.Visibility | MessageUpdateFields.Content); - - // Wait for message timeout to expire, then retrieve it again. - Thread.Sleep(TimeSpan.FromSeconds(1.5)); - CloudQueueMessage messageRetrievedAgain = queue.GetMessage(); - - // The content should have been modified. - Assert.AreEqual(messageFromQueue.AsString, messageRetrievedAgain.AsString); - - // Update with zero visibility timeout - queue.UpdateMessage(messageRetrievedAgain, TimeSpan.Zero, MessageUpdateFields.Visibility); - - // The message is now expired. Retrieve it again. - messageRetrievedAgain = queue.GetMessage(); - - // The content should be the same as before. - Assert.AreEqual(messageFromQueue.AsString, messageRetrievedAgain.AsString); - - queue.Delete(); - } - - [TestMethod] - [Description("Test update message with full parameters and APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUpdateMessageFullParameterAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - queue.AddMessage(new CloudQueueMessage("message in queue")); - CloudQueueMessage messageFromQueue = queue.GetMessage(TimeSpan.FromDays(1)); - DateTimeOffset nextVisibleTime = messageFromQueue.NextVisibleTime.Value; - - // Modify the message contents client-side - messageFromQueue.SetMessageContent("new message content!"); - - // Increase the message's visibility timeout. - IAsyncResult result = queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromDays(2), - MessageUpdateFields.Visibility, - ar => waitHandler.Set(), - null); - waitHandler.WaitOne(); - queue.EndUpdateMessage(result); - - - // The extra visibility time we get should be 1 day + small delta server time. - Assert.IsTrue(messageFromQueue.NextVisibleTime - nextVisibleTime >= TimeSpan.FromDays(1)); - - // Decrease the message's visibility timeout. - result = queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromDays(1), - MessageUpdateFields.Visibility, - ar => waitHandler.Set(), - null); - waitHandler.WaitOne(); - queue.EndUpdateMessage(result); - - // Now the extra time equals a small delta server time. - Assert.IsTrue(messageFromQueue.NextVisibleTime - nextVisibleTime < TimeSpan.FromHours(1)); - - // Update the message's visibility and content. - result = queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromSeconds(1), - MessageUpdateFields.Visibility | MessageUpdateFields.Content, - ar => waitHandler.Set(), - null); - waitHandler.WaitOne(); - queue.EndUpdateMessage(result); - - // Wait for message timeout to expire, then retrieve it again. - Thread.Sleep(TimeSpan.FromSeconds(1.5)); - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - CloudQueueMessage messageRetrievedAgain = queue.EndGetMessage(result); - - // The content should have been modified. - Assert.AreEqual(messageFromQueue.AsString, messageRetrievedAgain.AsString); - - // Update with zero visibility timeout and full parameters - result = queue.BeginUpdateMessage( - messageRetrievedAgain, - TimeSpan.Zero, - MessageUpdateFields.Visibility, - null, - new OperationContext(), - ar => waitHandler.Set(), - null); - waitHandler.WaitOne(); - queue.EndUpdateMessage(result); - - // The message is now expired. Retrieve it again. - result = queue.BeginGetMessage(ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - messageRetrievedAgain = queue.EndGetMessage(result); - - // The content should be the same as before. - Assert.AreEqual(messageFromQueue.AsString, messageRetrievedAgain.AsString); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test update Messgae boundary and negative check.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUpdateMessageBoundaryAndNegativeCheck() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - queue.AddMessage(new CloudQueueMessage("message in queue")); - CloudQueueMessage messageFromQueue = queue.GetMessage(TimeSpan.FromDays(1)); - - messageFromQueue.SetMessageContent("newer message content"); - - // If Visibility is not flagged for modification, an exception should be raised. - TestHelper.ExpectedException( - () => queue.UpdateMessage(messageFromQueue, TimeSpan.FromDays(1), MessageUpdateFields.Content), - "Visibility is not flagged for modification"); - - // If visibility timeout is greater than the maximum time to live, an exception should be raised. - TestHelper.ExpectedException( - () => queue.UpdateMessage(messageFromQueue, TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1), MessageUpdateFields.Visibility), - "visibility timeout is greater than the maximum time to live"); - - // If visibility timeout is negative, an exception should be raised. - TestHelper.ExpectedException( - () => queue.UpdateMessage(messageFromQueue, TimeSpan.FromSeconds(-1), MessageUpdateFields.Visibility), - "visibility timeout is negative"); - - // If the message has no ID and pop receipt, an exception should be raised. - CloudQueueMessage messageNotReceived = new CloudQueueMessage("This message has never been in a queue before."); - TestHelper.ExpectedException( - () => queue.UpdateMessage(messageNotReceived, TimeSpan.FromDays(1), MessageUpdateFields.Visibility), - "the message has no ID and pop receipt"); - - queue.Delete(); - } - - [TestMethod] - [Description("Test update Messgae boundary and negative check with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueUpdateMessageBoundaryAndNegativeCheckAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandler = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginAddMessage( - new CloudQueueMessage("message in queue"), ar => waitHandler.Set(), null); - waitHandler.WaitOne(); - queue.EndAddMessage(result); - - CloudQueueMessage messageFromQueue = queue.GetMessage(TimeSpan.FromDays(1)); - - messageFromQueue.SetMessageContent("newer message content"); - - // If Visibility is not flagged for modification, an exception should be raised. - TestHelper.ExpectedException( - () => - queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromDays(1), - MessageUpdateFields.Content, - ar => waitHandler.Set(), - null), - "Visibility is not flagged for modification"); - - // If visibility timeout is greater than the maximum time to live, an exception should be raised. - TestHelper.ExpectedException( - () => - queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1), - MessageUpdateFields.Visibility, - ar => waitHandler.Set(), - null), - "visibility timeout is greater than the maximum time to live"); - - // If visibility timeout is negative, an exception should be raised. - TestHelper.ExpectedException( - () => - queue.BeginUpdateMessage( - messageFromQueue, - TimeSpan.FromSeconds(-1), - MessageUpdateFields.Visibility, - ar => waitHandler.Set(), - null), - "visibility timeout is negative"); - - // If the message has no ID and pop receipt, an exception should be raised. - CloudQueueMessage messageNotReceived = new CloudQueueMessage("This message has never been in a queue before."); - TestHelper.ExpectedException( - () => - queue.BeginUpdateMessage( - messageNotReceived, - TimeSpan.FromDays(1), - MessageUpdateFields.Visibility, - ar => waitHandler.Set(), - null), - "the message has no ID and pop receipt"); - } - - queue.Delete(); - } - - [TestMethod] - [Description("Test get Messgae with full parameter.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageGetMessageFullParameter() - { - string data = "Visibility Test Message"; - CloudQueueMessage message; - - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - queue.AddMessage(new CloudQueueMessage(data)); - - // Expect failure from zero visibility timeout - TestHelper.ExpectedException( - () => queue.GetMessage(TimeSpan.Zero), - "Expect failure from zero visibility timeout"); - - // Expect failure from over 7 days visibility timeout - TestHelper.ExpectedException( - () => queue.GetMessage(TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1)), - "Expect failure from over 7 days visibility timeout"); - - // Test 1 second timeout (minimum) - message = queue.GetMessage(TimeSpan.FromSeconds(1)); - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Wait for the timeout to expire - Thread.Sleep(TimeSpan.FromSeconds(1)); - - // Test 7 day timeout (maximum) - message = queue.GetMessage(TimeSpan.FromDays(7)); - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Delete the message - queue.DeleteMessage(message); - - queue.Delete(); - } - - [TestMethod] - [Description("Test get message with full parameter with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageGetMessageFullParameterAPM() - { - string data = "Visibility Test Message"; - CloudQueueMessage message; - - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginAddMessage(new CloudQueueMessage(data), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndAddMessage(result); - - // Expect failure from zero visibility timeout - result = queue.BeginGetMessage(TimeSpan.Zero, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => queue.EndGetMessage(result), - "Expect failure from zero visibility timeout"); - - // Expect failure from over 7 days visibility timeout - result = queue.BeginGetMessage(TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1), null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TestHelper.ExpectedException( - () => queue.EndGetMessage(result), - "Expect failure from over 7 days visibility timeout"); - - // Test 1 second timeout (minimum) - result = queue.BeginGetMessage(TimeSpan.FromSeconds(1), null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - message = queue.EndGetMessage(result); - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Wait for the timeout to expire - Thread.Sleep(TimeSpan.FromSeconds(1)); - - // Test 7 day timeout (maximum) - result = queue.BeginGetMessage(TimeSpan.FromDays(7), null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - message = queue.EndGetMessage(result); - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Delete the message - result = queue.BeginDeleteMessage(message.Id, message.PopReceipt, null, null, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDeleteMessage(result); - } - - queue.Delete(); - } - -#if TASK - [TestMethod] - [Description("Test get Messgae with full parameter.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueMessageGetMessageFullParameterTask() - { - string data = "Visibility Test Message"; - CloudQueueMessage message; - - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - - queue.AddMessageAsync(new CloudQueueMessage(data)).Wait(); - - // Expect failure from zero visibility timeout - TestHelper.ExpectedExceptionTask( - queue.GetMessageAsync(TimeSpan.Zero, null, null), - "Expect failure from zero visibility timeout"); - - // Expect failure from over 7 days visibility timeout - TestHelper.ExpectedExceptionTask( - queue.GetMessageAsync(TimeSpan.FromDays(7) + TimeSpan.FromSeconds(1), null, null), - "Expect failure from over 7 days visibility timeout"); - - // Test 1 second timeout (minimum) - message = queue.GetMessageAsync(TimeSpan.FromSeconds(1), null, null).Result; - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Wait for the timeout to expire - Thread.Sleep(TimeSpan.FromSeconds(1)); - - // Test 7 day timeout (maximum) - message = queue.GetMessageAsync(TimeSpan.FromDays(7), null, null).Result; - Assert.IsNotNull(message); - Assert.AreEqual(message.AsString, data); - - // Delete the message - queue.DeleteMessageAsync(message.Id, message.PopReceipt, null, null).Wait(); - - queue.DeleteAsync().Wait(); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueTest.cs deleted file mode 100644 index 3c12d93f21957..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/CloudQueueTest.cs +++ /dev/null @@ -1,1478 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Threading; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; - -#if WINDOWS_DESKTOP -using System.Threading.Tasks; -#endif - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create and delete a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateAndDelete() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - queue.Delete(); - } - - [TestMethod] - [Description("Create and delete a queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateAndDeleteAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginCreate(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndCreate(result); - - result = queue.BeginExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndExists(result)); - - result = queue.BeginDelete(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDelete(result); - } - } - -#if TASK - [TestMethod] - [Description("Create and delete a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateAndDeleteTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.CreateAsync().Wait(); - queue.ExistsAsync().Wait(); - queue.DeleteAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Create and delete a queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateAndDeleteFullParameterAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginCreate(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndCreate(result); - - result = queue.BeginExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndExists(result)); - - result = queue.BeginDelete(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDelete(result); - } - } - -#if TASK - [TestMethod] - [Description("Create and delete a queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateAndDeleteFullParameterTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - queue.CreateAsync(null, new OperationContext()).Wait();; - - Assert.IsTrue(queue.ExistsAsync(null, new OperationContext()).Result); - - queue.DeleteAsync(null, new OperationContext()).Wait(); - } -#endif - - [TestMethod] - [Description("Create and delete a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateFromUri() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - queue.Create(); - - // Create cloud queue from constructor - CloudQueue sameQueue = new CloudQueue(queue.Uri); - - // Test that queue is the same - Assert.IsTrue(sameQueue.Name.Equals(queue.Name)); - Assert.IsTrue(sameQueue.Uri.Equals(queue.Uri)); - - queue.Delete(); - } - - [TestMethod] - [Description("Create a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateUsingDifferentVersionHeader() - { - string name = GenerateNewQueueName(); - - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - OperationContext opContext = new OperationContext(); - opContext.SendingRequest += (obj, args) => args.Request.Headers[Constants.HeaderConstants.StorageVersionHeader] = "2011-08-18"; - - queue.Create(null, opContext); - Assert.AreEqual((int)HttpStatusCode.Created, opContext.LastResult.HttpStatusCode); - - queue.DeleteIfExists(); - } - - [TestMethod] - [Description("Create a queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateUsingDifferentVersionHeaderAPM() - { - string name = GenerateNewQueueName(); - - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - OperationContext opContext = new OperationContext(); - opContext.SendingRequest += (obj, args) => args.Request.Headers[Constants.HeaderConstants.StorageVersionHeader] = "2011-08-18"; - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginCreate(null, opContext, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndCreate(result); - - Assert.AreEqual((int)HttpStatusCode.Created, opContext.LastResult.HttpStatusCode); - - result = queue.BeginDeleteIfExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndDeleteIfExists(result); - } - } - -#if TASK - [TestMethod] - [Description("Create a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateUsingDifferentVersionHeaderTask() - { - string name = GenerateNewQueueName(); - - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - OperationContext opContext = new OperationContext(); - opContext.SendingRequest += (obj, args) => args.Request.Headers[Constants.HeaderConstants.StorageVersionHeader] = "2011-08-18"; - - queue.CreateAsync(null, opContext).Wait(); - Assert.AreEqual((int)HttpStatusCode.Created, opContext.LastResult.HttpStatusCode); - - queue.DeleteIfExistsAsync().Wait(); - } -#endif - - [TestMethod] - [Description("Try to create a queue after it is created")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateIfNotExists() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - Assert.IsTrue(queue.CreateIfNotExists()); - Assert.IsFalse(queue.CreateIfNotExists()); - } - finally - { - queue.Delete(); - } - } - - [TestMethod] - [Description("Try to create a queue after it is created with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateIfNotExistsAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginCreateIfNotExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndCreateIfNotExists(result)); - - result = queue.BeginCreateIfNotExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndCreateIfNotExists(result)); - } - } - finally - { - queue.Delete(); - } - } - - [TestMethod] - [Description("Try to create a queue after it is created with APM.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateIfNotExistsFullParameterAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginCreateIfNotExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndCreateIfNotExists(result)); - - result = queue.BeginCreateIfNotExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndCreateIfNotExists(result)); - } - } - finally - { - queue.Delete(); - } - } - -#if TASK - [TestMethod] - [Description("Try to create a queue after it is created")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateIfNotExistsTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - Assert.IsTrue(queue.CreateIfNotExistsAsync().Result); - Assert.IsFalse(queue.CreateIfNotExistsAsync().Result); - } - finally - { - queue.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Try to create a queue after it is created")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCreateIfNotExistsFullParameterTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - Assert.IsTrue(queue.CreateIfNotExistsAsync(null, new OperationContext()).Result); - Assert.IsFalse(queue.CreateIfNotExistsAsync(null, new OperationContext()).Result); - } - finally - { - queue.DeleteAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Try to delete a non-existing queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueDeleteIfExists() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - Assert.IsFalse(queue.DeleteIfExists()); - queue.Create(); - Assert.IsTrue(queue.DeleteIfExists()); - Assert.IsFalse(queue.DeleteIfExists()); - } - - [TestMethod] - [Description("Try to delete a non-existing queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueDeleteIfExistsAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginDeleteIfExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndDeleteIfExists(result)); - - result = queue.BeginCreate(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndCreate(result); - - result = queue.BeginDeleteIfExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndDeleteIfExists(result)); - - result = queue.BeginDeleteIfExists(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndDeleteIfExists(result)); - } - } - - [TestMethod] - [Description("Try to delete a non-existing queue with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueDeleteIfExistsFullParameterAPM() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginDeleteIfExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndDeleteIfExists(result)); - - result = queue.BeginCreate(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndCreate(result); - - result = queue.BeginDeleteIfExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsTrue(queue.EndDeleteIfExists(result)); - - result = queue.BeginDeleteIfExists(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - Assert.IsFalse(queue.EndDeleteIfExists(result)); - } - } - -#if TASK - [TestMethod] - [Description("Try to delete a non-existing queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueDeleteIfExistsTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - Assert.IsFalse(queue.DeleteIfExistsAsync().Result); - queue.CreateAsync().Wait(); - Assert.IsTrue(queue.DeleteIfExistsAsync().Result); - Assert.IsFalse(queue.DeleteIfExistsAsync().Result); - } - - [TestMethod] - [Description("Try to delete a non-existing queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueDeleteIfExistsFullParametersTask() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - Assert.IsFalse(queue.DeleteIfExistsAsync(null, new OperationContext()).Result); - queue.CreateAsync().Wait(); - Assert.IsTrue(queue.DeleteIfExistsAsync(null, new OperationContext()).Result); - Assert.IsFalse(queue.DeleteIfExistsAsync(null, new OperationContext()).Result); - } -#endif - - [TestMethod] - [Description("Set/get queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetSetPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - QueuePermissions emptyPermission = queue.GetPermissions(); - Assert.AreEqual(emptyPermission.SharedAccessPolicies.Count, 0); - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add - | SharedAccessQueuePermissions.ProcessMessages - | SharedAccessQueuePermissions.Read - | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add( - id, - new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - queue.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - QueuePermissions permissionsToRetrieve = queueToRetrieve.GetPermissions(); - - AssertPermissionsEqual(permissions, permissionsToRetrieve); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set/get queue permissions with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetSetPermissionsAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queue.BeginGetPermissions(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueuePermissions emptyPermission = queue.EndGetPermissions(result); - - Assert.AreEqual(emptyPermission.SharedAccessPolicies.Count, 0); - - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - result = queue.BeginSetPermissions(permissions, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndSetPermissions(result); - - Thread.Sleep(30 * 1000); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - - result = queueToRetrieve.BeginGetPermissions(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - QueuePermissions permissionsToRetrieve = queueToRetrieve.EndGetPermissions(result); - - AssertPermissionsEqual(permissions, permissionsToRetrieve); - } - } - finally - { - queue.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Set/get queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetSetPermissionsTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.CreateAsync().Wait(); - QueuePermissions emptyPermission = queue.GetPermissionsAsync().Result; - Assert.AreEqual(emptyPermission.SharedAccessPolicies.Count, 0); - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add - | SharedAccessQueuePermissions.ProcessMessages - | SharedAccessQueuePermissions.Read - | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add( - id, - new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - queue.SetPermissionsAsync(permissions).Wait(); - Thread.Sleep(30 * 1000); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - QueuePermissions permissionsToRetrieve = queueToRetrieve.GetPermissionsAsync(null, null).Result; - - AssertPermissionsEqual(permissions, permissionsToRetrieve); - } - finally - { - queue.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Set/get a queue with metadata")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueSetGetMetadata() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - queueToRetrieve.FetchAttributes(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - queue.Metadata.Add("key1", "value1"); - queue.SetMetadata(); - - queueToRetrieve.FetchAttributes(); - Assert.AreEqual(1, queueToRetrieve.Metadata.Count); - Assert.AreEqual("value1", queueToRetrieve.Metadata["key1"]); - - queue.Metadata.Clear(); - queue.SetMetadata(); - - queueToRetrieve.FetchAttributes(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set/get a queue with metadata with APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueSetGetMetadataAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - IAsyncResult result = queueToRetrieve.BeginFetchAttributes(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queueToRetrieve.EndFetchAttributes(result); - - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - queue.Metadata.Add("key1", "value1"); - result = queue.BeginSetMetadata(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndSetMetadata(result); - - result = queueToRetrieve.BeginFetchAttributes(ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queueToRetrieve.EndFetchAttributes(result); - Assert.AreEqual(1, queueToRetrieve.Metadata.Count); - Assert.AreEqual("value1", queueToRetrieve.Metadata["key1"]); - - queue.Metadata.Clear(); - result = queue.BeginSetMetadata(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queue.EndSetMetadata(result); - - result = queueToRetrieve.BeginFetchAttributes(null, new OperationContext(), ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - queueToRetrieve.EndFetchAttributes(result); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - } - } - finally - { - queue.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Set/get a queue with metadata")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueSetGetMetadataTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.CreateAsync().Wait(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - queueToRetrieve.FetchAttributesAsync().Wait(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - queue.Metadata.Add("key1", "value1"); - queue.SetMetadataAsync().Wait(); - - queueToRetrieve.FetchAttributesAsync().Wait(); - Assert.AreEqual(1, queueToRetrieve.Metadata.Count); - Assert.AreEqual("value1", queueToRetrieve.Metadata["key1"]); - - queue.Metadata.Clear(); - queue.SetMetadataAsync(null, new OperationContext()).Wait(); - - queueToRetrieve.FetchAttributesAsync(null, new OperationContext()).Wait(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - } - finally - { - queue.DeleteIfExistsAsync().Wait(); - } - } -#endif - - [TestMethod] - [Description("Test queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueSASTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessage(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - queue.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - - CloudStorageAccount sasAcc = new CloudStorageAccount(sasCredsFromId, new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint), new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint), new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint)); - CloudQueueClient sasClient = sasAcc.CreateCloudQueueClient(); - - CloudQueue sasQueueFromSasUri = new CloudQueue(sasClient.Credentials.TransformUri(queue.Uri)); - CloudQueueMessage receivedMessage = sasQueueFromSasUri.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage.AsString); - - CloudQueue sasQueueFromSasUri1 = new CloudQueue(new Uri(queue.Uri.ToString() + sasTokenFromId)); - CloudQueueMessage receivedMessage1 = sasQueueFromSasUri1.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage2 = sasQueueFromId.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage3 = sasQueueFromPolicy.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage3.AsString); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test queue sas with Italy regional settings")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueRegionalSASTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT"); - - try - { - queue.Create(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessage(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - queue.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage1 = sasQueueFromId.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage2 = sasQueueFromPolicy.PeekMessage(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Set queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueSetPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - queue.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - CloudQueue queue2 = queue.ServiceClient.GetQueueReference(queue.Name); - permissions = queue2.GetPermissions(); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessQueuePermissions.Read, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Clear queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClearPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - queue.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - - Assert.AreEqual(true, permissions.SharedAccessPolicies.Contains(sharedAccessPolicy)); - Assert.AreEqual(true, permissions.SharedAccessPolicies.ContainsKey("key1")); - permissions.SharedAccessPolicies.Clear(); - queue.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Copy queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueCopyPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry2 = start.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - - KeyValuePair[] sharedAccessPolicyArray = new KeyValuePair[2]; - permissions.SharedAccessPolicies.CopyTo(sharedAccessPolicyArray, 0); - Assert.AreEqual(2, sharedAccessPolicyArray.Length); - Assert.AreEqual(sharedAccessPolicy, sharedAccessPolicyArray[0]); - Assert.AreEqual(sharedAccessPolicy2, sharedAccessPolicyArray[1]); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Remove queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueRemovePermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - queue.SetPermissions(permissions); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions.SharedAccessPolicies.Remove(sharedAccessPolicy2); - queue.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - permissions = queue.GetPermissions(); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.AreEqual(sharedAccessPolicy.Key, permissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, permissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - queue.SetPermissions(permissions); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions.SharedAccessPolicies.Remove("key2"); - queue.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - permissions = queue.GetPermissions(); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.AreEqual(sharedAccessPolicy.Key, permissions.SharedAccessPolicies.ElementAt(0).Key); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, permissions.SharedAccessPolicies.ElementAt(0).Value.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, permissions.SharedAccessPolicies.ElementAt(0).Value.SharedAccessExpiryTime); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("TryGetValue for queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTryGetValuePermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - queue.SetPermissions(permissions); - Thread.Sleep(3 * 1000); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - permissions = queue.GetPermissions(); - SharedAccessQueuePolicy retrPolicy; - permissions.SharedAccessPolicies.TryGetValue("key1", out retrPolicy); - Assert.AreEqual(sharedAccessPolicy.Value.Permissions, retrPolicy.Permissions); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessStartTime, retrPolicy.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy.Value.SharedAccessExpiryTime, retrPolicy.SharedAccessExpiryTime); - - SharedAccessQueuePolicy retrPolicy2; - permissions.SharedAccessPolicies.TryGetValue("key2", out retrPolicy2); - Assert.AreEqual(sharedAccessPolicy2.Value.Permissions, retrPolicy2.Permissions); - Assert.AreEqual(sharedAccessPolicy2.Value.SharedAccessStartTime, retrPolicy2.SharedAccessStartTime); - Assert.AreEqual(sharedAccessPolicy2.Value.SharedAccessExpiryTime, retrPolicy2.SharedAccessExpiryTime); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("GetEnumerator for queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetEnumeratorPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - IEnumerator> policies = permissions.SharedAccessPolicies.GetEnumerator(); - policies.MoveNext(); - Assert.AreEqual(sharedAccessPolicy, policies.Current); - policies.MoveNext(); - Assert.AreEqual(sharedAccessPolicy2, policies.Current); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("GetValues for queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueGetValuesPermissions() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - try - { - queue.Create(); - - QueuePermissions permissions = queue.GetPermissions(); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - KeyValuePair sharedAccessPolicy = new KeyValuePair("key1", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessQueuePermissions.Read, - }); - - DateTime start2 = DateTime.UtcNow; - start2 = new DateTime(start2.Year, start2.Month, start2.Day, start2.Hour, start2.Minute, start2.Second, DateTimeKind.Utc); - DateTime expiry2 = start2.AddMinutes(30); - KeyValuePair sharedAccessPolicy2 = new KeyValuePair("key2", new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start2, - SharedAccessExpiryTime = expiry2, - Permissions = SharedAccessQueuePermissions.Read, - }); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy); - permissions.SharedAccessPolicies.Add(sharedAccessPolicy2); - Assert.AreEqual(2, permissions.SharedAccessPolicies.Count); - - ICollection values = permissions.SharedAccessPolicies.Values; - Assert.AreEqual(2, values.Count); - Assert.AreEqual(sharedAccessPolicy.Value, values.ElementAt(0)); - Assert.AreEqual(sharedAccessPolicy2.Value, values.ElementAt(1)); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Update queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void UpdateQueueSASTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - queue.Create(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - queue.AddMessage(message); - SharedAccessQueuePolicy policy = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages, - }; - string id = Guid.NewGuid().ToString(); - string sasToken = queue.GetSharedAccessSignature(policy, null); - - StorageCredentials sasCreds = new StorageCredentials(sasToken); - CloudQueue sasQueue = new CloudQueue(queue.Uri, sasCreds); - - TestHelper.ExpectedException( - () => sasQueue.PeekMessage(), - "Peek when Sas does not allow Read access on the queue", - HttpStatusCode.NotFound); - - sasQueue.AddMessage(message); - - SharedAccessQueuePolicy policy2 = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read, - }; - - string sasToken2 = queue.GetSharedAccessSignature(policy2, null); - sasCreds.UpdateSASToken(sasToken2); - sasQueue = new CloudQueue(queue.Uri, sasCreds); - - sasQueue.PeekMessage(); - } - finally - { - queue.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test queue listing")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListQueuesSegmentedTest() - { - String prefix = "pagingqueuetest" + Guid.NewGuid(); - CloudQueueClient client = GenerateCloudQueueClient(); - ///Create 20 queues - for (int i = 1; i <= 20; i++) - { - CloudQueue myqueue = client.GetQueueReference(prefix + i); - myqueue.CreateIfNotExists(); - } - - ///Segmented listing of queues. - ///Return a page of 10 queues beginning with the specified prefix. - ///Check with options and context as NULL - QueueResultSegment resultSegment = client.ListQueuesSegmented(prefix, QueueListingDetails.None, 10, null, null, null); - - IEnumerable list = resultSegment.Results; - int count = 0; - foreach (CloudQueue item in list) - { - count++; - item.Delete(); - } - Assert.AreEqual(10, count); - Assert.IsNotNull(resultSegment.ContinuationToken); - - OperationContext context = new OperationContext(); - QueueRequestOptions options = new QueueRequestOptions(); - - ///Check with options and context having some value - - QueueResultSegment resultSegment2 = client.ListQueuesSegmented(prefix, QueueListingDetails.None, 10, resultSegment.ContinuationToken, options, context); - IEnumerable list2 = resultSegment2.Results; - foreach (CloudQueue item in list2) - { - item.Delete(); - } - Assert.IsNull(resultSegment2.ContinuationToken); - } - - [TestMethod] - [Description("Test empty headers")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueEmptyHeaderSigningTest() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(Guid.NewGuid().ToString("N")); - OperationContext context = new OperationContext(); - try - { - context.UserHeaders = new Dictionary(); - context.UserHeaders.Add("x-ms-foo", String.Empty); - queue.Create(null, context); - CloudQueueMessage message = new CloudQueueMessage("Hello Signing"); - queue.AddMessage(message, null, null, null, context); - } - finally - { - queue.DeleteIfExists(); - } - } - - #region Test Helpers - internal static void AssertPermissionsEqual(QueuePermissions permissions1, QueuePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessQueuePolicy policy1 = pair.Value; - SharedAccessQueuePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueAnalyticsUnitTests.cs deleted file mode 100644 index 548703446bcd6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueAnalyticsUnitTests.cs +++ /dev/null @@ -1,427 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class QueueAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public QueueAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudQueueClient client = GenerateCloudQueueClient(); - startProperties = client.GetServiceProperties(); - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudQueueClient client = GenerateCloudQueueClient(); - client.SetServiceProperties(startProperties); - - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - #endregion - - #region Analytics RoundTrip - - #region Sync - - [TestMethod] - [Description("Test Analytics Round Trip Sync")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsRoundTripSync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Analytics Round Trip APM")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsRoundTripAPM() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginSetServiceProperties(props, (res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - client.EndSetServiceProperties(result); - } - - ServiceProperties retrievedProps = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginGetServiceProperties((res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - retrievedProps = client.EndGetServiceProperties(result); - } - - AssertServicePropertiesAreEqual(props, retrievedProps); - } - - #endregion - - #region Task - - [TestMethod] - [Description("Test Analytics Round Trip Task")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsRoundTripTask() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServicePropertiesAsync(props).Wait(); - - AssertServicePropertiesAreEqual(props, client.GetServicePropertiesAsync().Result); - } - - #endregion - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsDisable() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsDefaultServiceVersionThrows() - { - CloudQueueClient client = GenerateCloudQueueClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - client.SetServiceProperties(props, null, ctx); - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.Message, "The remote server returned an error: (400) Bad Request."); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsLoggingOperations() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsMetricsLevel() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueTestAnalyticsRetentionPolicies() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueCancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueCancellationUnitTests.cs deleted file mode 100644 index d12114965a622..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Queue/QueueCancellationUnitTests.cs +++ /dev/null @@ -1,92 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class QueueCancellationUnitTests : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Test Set Queue ACL Cancellation")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueSetACLCancellation() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - QueuePermissions permissions = new QueuePermissions(); - permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update - }); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.QueueTraffic().IfHostNameContains(client.Credentials.AccountName)) }, - (options, opContext, callback, state) => queue.BeginSetPermissions(permissions, (QueueRequestOptions)options, opContext, callback, state), - queue.EndSetPermissions); - } - - [TestMethod] - [Description("Test Get Queue ACL Cancellation")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void QueueGetACLCancellation() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - TestHelper.ExecuteAPMMethodWithCancellation(4000, - new[] { DelayBehaviors.DelayAllRequestsIf(4000 * 3, XStoreSelectors.QueueTraffic().IfHostNameContains(client.Credentials.AccountName)) }, - (options, opContext, callback, state) => queue.BeginGetPermissions((QueueRequestOptions)options, opContext, callback, state), - (res) => queue.EndGetPermissions(res)); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/StorageExceptionTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/StorageExceptionTests.cs deleted file mode 100644 index b51ef39ca4d47..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/StorageExceptionTests.cs +++ /dev/null @@ -1,264 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ -#if !WINDOWS_PHONE - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.WindowsAzure.Storage.Blob; - using System; - using System.Collections.Generic; - using System.IO; - using System.Runtime.Serialization.Formatters.Binary; - using System.Security.Cryptography; - using System.Text; - using System.Xml; - - [TestClass] - public class StorageExceptionTests - { - [TestMethod] - [Description("Persist and read back StorageException")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void StorageExceptionVerifyXml() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); - try - { - container.Create(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - byte[] buffer = new byte[1024]; - Random random = new Random(); - random.NextBytes(buffer); - - using(MemoryStream stream = new MemoryStream(buffer)) - { - blob.UploadFromStream(stream); - } - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - StorageException e = TestHelper.ExpectedException( - () => blob2.FetchAttributes(), - "Fetching attributes of a block blob using a page blob reference should fail"); - - using (Stream s = new MemoryStream()) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Serialize(s, e); - s.Position = 0; // Reset stream position - StorageException e2 = (StorageException)formatter.Deserialize(s); - - Assert.IsInstanceOfType(e2.InnerException, typeof(InvalidOperationException)); - Assert.AreEqual(e.IsRetryable, e2.IsRetryable); - Assert.AreEqual(e.RequestInformation.HttpStatusCode, e2.RequestInformation.HttpStatusCode); - Assert.AreEqual(e.RequestInformation.HttpStatusMessage, e2.RequestInformation.HttpStatusMessage); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Persist and read back ExtendedErrorInfo")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ExtendedErrorInfoVerifyXml() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); - - try - { - StorageException e = TestHelper.ExpectedException( - () => container.GetPermissions(), - "Try to get permissions on a non-existent container"); - - Assert.IsNotNull(e.RequestInformation.ExtendedErrorInformation); - - StorageExtendedErrorInformation retrErrorInfo = new StorageExtendedErrorInformation(); - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - e.RequestInformation.ExtendedErrorInformation.WriteXml(writer); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - retrErrorInfo.ReadXml(reader); - } - - Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorCode, retrErrorInfo.ErrorCode); - Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorMessage, retrErrorInfo.ErrorMessage); - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Persist and read back ExtendedErrorInfo")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ExtendedErrorInfoVerifyXmlWithAdditionalDetails() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient client = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = client.GetContainerReference(Guid.NewGuid().ToString("N")); - - byte[] buffer = TestBase.GetRandomBuffer(4 * 1024 * 1024); - MD5 md5 = MD5.Create(); - string contentMD5 = Convert.ToBase64String(md5.ComputeHash(buffer)); - - try - { - container.Create(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - List blocks = new List(); - for (int i = 0; i < 2; i++) - { - blocks.Add(Convert.ToBase64String(Guid.NewGuid().ToByteArray())); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - memoryStream.Seek(0, SeekOrigin.Begin); - blob.PutBlock(blocks[0], memoryStream, contentMD5); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - StorageException e = TestHelper.ExpectedException( - () => blob.PutBlock(blocks[1], memoryStream, contentMD5), - "Invalid MD5 should fail with mismatch"); - - Assert.IsNotNull(e.RequestInformation.ExtendedErrorInformation); - - StorageExtendedErrorInformation retrErrorInfo = new StorageExtendedErrorInformation(); - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - e.RequestInformation.ExtendedErrorInformation.WriteXml(writer); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - retrErrorInfo.ReadXml(reader); - } - - Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorCode, retrErrorInfo.ErrorCode); - Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.ErrorMessage, retrErrorInfo.ErrorMessage); - Assert.AreNotEqual(0, retrErrorInfo.AdditionalDetails.Count); - Assert.AreEqual(e.RequestInformation.ExtendedErrorInformation.AdditionalDetails.Count, retrErrorInfo.AdditionalDetails.Count); - } - } - finally - { - container.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Persist and read back RequestResult")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void RequestResultVerifyXml() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient blobClient = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - - OperationContext opContext = new OperationContext(); - Assert.IsNull(opContext.LastResult); - container.Exists(null, opContext); - Assert.IsNotNull(opContext.LastResult); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = opContext.LastResult.StartTime; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second); - - DateTime end = opContext.LastResult.EndTime; - end = new DateTime(end.Year, end.Month, end.Day, end.Hour, end.Minute, end.Second); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - opContext.LastResult.WriteXml(writer); - } - - RequestResult retrResult = new RequestResult(); - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - retrResult.ReadXml(reader); - } - - Assert.AreEqual(opContext.LastResult.RequestDate, retrResult.RequestDate); - Assert.AreEqual(opContext.LastResult.ServiceRequestID, retrResult.ServiceRequestID); - Assert.AreEqual(start, retrResult.StartTime); - Assert.AreEqual(end, retrResult.EndTime); - Assert.AreEqual(opContext.LastResult.HttpStatusCode, retrResult.HttpStatusCode); - Assert.AreEqual(opContext.LastResult.HttpStatusMessage, retrResult.HttpStatusMessage); - Assert.AreEqual(opContext.LastResult.ContentMd5, retrResult.ContentMd5); - Assert.AreEqual(opContext.LastResult.Etag, retrResult.Etag); - - // Now test with no indentation - sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb)) - { - opContext.LastResult.WriteXml(writer); - } - - retrResult = new RequestResult(); - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - retrResult.ReadXml(reader); - } - - Assert.AreEqual(opContext.LastResult.RequestDate, retrResult.RequestDate); - Assert.AreEqual(opContext.LastResult.ServiceRequestID, retrResult.ServiceRequestID); - Assert.AreEqual(start, retrResult.StartTime); - Assert.AreEqual(end, retrResult.EndTime); - Assert.AreEqual(opContext.LastResult.HttpStatusCode, retrResult.HttpStatusCode); - Assert.AreEqual(opContext.LastResult.HttpStatusMessage, retrResult.HttpStatusMessage); - Assert.AreEqual(opContext.LastResult.ContentMd5, retrResult.ContentMd5); - Assert.AreEqual(opContext.LastResult.Etag, retrResult.Etag); - } - } -#endif -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableCRUDUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableCRUDUnitTests.cs deleted file mode 100644 index 7b62856f8f541..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableCRUDUnitTests.cs +++ /dev/null @@ -1,1146 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Summary description for CloudTableCRUDUnitTests - /// - [TestClass] - public class CloudTableCRUDUnitTests : TableTestBase - { - #region Locals + Ctors - public CloudTableCRUDUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // - // Use TestInitialize to run code before running each test - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - #endregion - - #region Table Create - - #region Sync - - [TestMethod] - [Description("Test Table Create - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test Table Create When Table Already Exists - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateAlreadyExistsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - - // This should throw with no retries - tableRef.Create(null, ctx); - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "TableAlreadyExists"); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.Conflict); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test Table Create From URI - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateFromUriSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - tableRef.Create(); - - // Get reference from URI - CloudTable sameTableRef = new CloudTable(tableRef.Uri); - - try - { - Assert.IsTrue(sameTableRef.Name.Equals(tableRef.Name)); - Assert.IsTrue(sameTableRef.Uri.Equals(tableRef.Uri)); - } - finally - { - tableRef.DeleteIfExists(); - } - } - #endregion - - #region APM - - [TestMethod] - [Description("Test Table Create - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginCreate((res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - tableRef.EndCreate(result); - } - - Assert.IsTrue(tableRef.Exists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test Table Create When Table Already Exists - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateAlreadyExistsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - - // This should throw with no retries - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginCreate( - null, - ctx, - (res) => - { - result = res; - evt.Set(); - }, - null); - evt.WaitOne(); - - tableRef.EndCreate(result); - } - - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "TableAlreadyExists"); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.Conflict); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExists(); - } - } - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Table Create - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - tableRef.CreateAsync().Wait(); - Assert.IsTrue(tableRef.ExistsAsync().Result); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table Create When Table Already Exists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateAlreadyExistsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - tableRef.CreateAsync().Wait(); - Assert.IsTrue(tableRef.ExistsAsync().Result); - - // This should throw with no retries - tableRef.CreateAsync(null, ctx).Wait(); - - Assert.Fail(); - } - catch (AggregateException e) - { - StorageException ex = e.InnerException as StorageException; - if (ex == null) - { - throw; - } - - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "TableAlreadyExists"); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.Conflict); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExists(); - } - } -#endif - - #endregion - - #endregion - - #region Table CreateIfNotExists - - #region Sync - - [TestMethod] - [Description("Test Table CreateIfNotExists - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - Assert.IsTrue(tableRef.CreateIfNotExists()); - Assert.IsTrue(tableRef.Exists()); - Assert.IsFalse(tableRef.CreateIfNotExists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Table CreateIfNotExists - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - // Assert Table does not exist - Assert.IsFalse(tableRef.Exists()); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginCreateIfNotExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should have been created - Assert.IsTrue(tableRef.EndCreateIfNotExists(result)); - } - - // Assert Table exists - Assert.IsTrue(tableRef.Exists()); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginCreateIfNotExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should not have been created - Assert.IsFalse(tableRef.EndCreateIfNotExists(result)); - } - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Table CreateIfNotExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - Assert.IsTrue(tableRef.CreateIfNotExistsAsync().Result); - Assert.IsTrue(tableRef.ExistsAsync().Result); - Assert.IsFalse(tableRef.CreateIfNotExistsAsync().Result); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table CreateIfNotExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsTrue(table.CreateIfNotExistsAsync(cancellationToken).Result); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsFalse(table.CreateIfNotExistsAsync(cancellationToken).Result); - Assert.IsTrue(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table CreateIfNotExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsTrue(table.CreateIfNotExistsAsync(requestOptions, operationContext).Result); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsFalse(table.CreateIfNotExistsAsync(requestOptions, operationContext).Result); - Assert.IsTrue(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table CreateIfNotExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableCreateIfNotExistsRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsTrue(table.CreateIfNotExistsAsync(requestOptions, operationContext, cancellationToken).Result); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsFalse(table.CreateIfNotExistsAsync(requestOptions, operationContext, cancellationToken).Result); - Assert.IsTrue(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } -#endif - - #endregion - - #endregion - - #region Table Delete - - #region Sync - - [TestMethod] - [Description("Test Table Delete - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - tableRef.Delete(); - Assert.IsFalse(tableRef.Exists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test Table Delete When Table Does Not Exist - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteWhenNotExistSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.Exists()); - - // This should throw with no retries - tableRef.Delete(null, ctx); - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 404); - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExists(); - } - } - #endregion - - #region APM - - [TestMethod] - [Description("Test Table Delete - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginDelete((res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - tableRef.EndDelete(result); - } - - Assert.IsFalse(tableRef.Exists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - [TestMethod] - [Description("Test Table Delete When Table Does Not Exist - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteWhenNotExistAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.Exists()); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginDelete( - null, - ctx, - (res) => - { - result = res; - evt.Set(); - }, - null); - evt.WaitOne(); - - tableRef.EndDelete(result); - } - - Assert.Fail(); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 404); - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExists(); - } - } - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Table Delete - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - tableRef.CreateAsync().Wait(); - Assert.IsTrue(tableRef.ExistsAsync().Result); - tableRef.DeleteAsync().Wait(); - Assert.IsFalse(tableRef.ExistsAsync().Result); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table Delete When Table Does Not Exist - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteWhenNotExistTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - - // This should throw with no retries - tableRef.DeleteAsync(null, ctx).Wait(); - Assert.Fail(); - } - catch (AggregateException e) - { - StorageException ex = e.InnerException as StorageException; - if (ex == null) - { - throw; - } - - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 404); - Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } -#endif - - #endregion - - #endregion - - #region Table DeleteIfExists - - #region Sync - - [TestMethod] - [Description("Test Table DeleteIfExists - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - Assert.IsFalse(tableRef.DeleteIfExists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - Assert.IsTrue(tableRef.DeleteIfExists()); - Assert.IsFalse(tableRef.DeleteIfExists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Table DeleteIfExists - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - // Assert Table does not exist - Assert.IsFalse(tableRef.Exists()); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginDeleteIfExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should not have been deleted as it doesnt exist - Assert.IsFalse(tableRef.EndDeleteIfExists(result)); - } - - // Assert Table exists - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginDeleteIfExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should have been deleted - Assert.IsTrue(tableRef.EndDeleteIfExists(result)); - } - - // Assert Table Was Deleted - Assert.IsFalse(tableRef.DeleteIfExists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Table DeleteIfExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - Assert.IsFalse(tableRef.DeleteIfExistsAsync().Result); - tableRef.CreateAsync().Wait(); - Assert.IsTrue(tableRef.ExistsAsync().Result); - Assert.IsTrue(tableRef.DeleteIfExistsAsync().Result); - Assert.IsFalse(tableRef.DeleteIfExistsAsync().Result); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table DeleteIfExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(cancellationToken).Result); - table.CreateAsync().Wait(); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsTrue(table.DeleteIfExistsAsync(cancellationToken).Result); - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(cancellationToken).Result); - Assert.IsFalse(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table DeleteIfExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(requestOptions, operationContext).Result); - table.CreateAsync().Wait(); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsTrue(table.DeleteIfExistsAsync(requestOptions, operationContext).Result); - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(requestOptions, operationContext).Result); - Assert.IsFalse(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table DeleteIfExists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableDeleteIfExistsRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(requestOptions, operationContext, cancellationToken).Result); - table.CreateAsync().Wait(); - Assert.IsTrue(table.ExistsAsync().Result); - Assert.IsTrue(table.DeleteIfExistsAsync(requestOptions, operationContext, cancellationToken).Result); - Assert.IsFalse(table.ExistsAsync().Result); - Assert.IsFalse(table.DeleteIfExistsAsync(requestOptions, operationContext, cancellationToken).Result); - Assert.IsFalse(table.ExistsAsync().Result); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } -#endif - - #endregion - - #endregion - - #region Table Exists - - #region Sync - - [TestMethod] - [Description("Test Table Exists - Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableExistsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.Exists()); - tableRef.Create(); - Assert.IsTrue(tableRef.Exists()); - tableRef.Delete(); - Assert.IsFalse(tableRef.Exists()); - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Table Exists - APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableExistsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should not have been deleted as it doesnt exist - Assert.IsFalse(tableRef.EndExists(result)); - } - - tableRef.Create(); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should not have been deleted as it doesnt exist - Assert.IsTrue(tableRef.EndExists(result)); - } - - tableRef.Delete(); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - tableRef.BeginExists((res) => - { - result = res; - evt.Set(); - }, null); - - evt.WaitOne(); - - // Table should not have been deleted as it doesnt exist - Assert.IsFalse(tableRef.EndExists(result)); - } - } - finally - { - tableRef.DeleteIfExists(); - } - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Table Exists - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableExistsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(tableRef.ExistsAsync().Result); - tableRef.CreateAsync().Wait(); - Assert.IsTrue(tableRef.ExistsAsync().Result); - tableRef.DeleteAsync().Wait(); - Assert.IsFalse(tableRef.ExistsAsync().Result); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } -#endif - - #endregion - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableClientTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableClientTests.cs deleted file mode 100644 index e30852ca2f9b9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/CloudTableClientTests.cs +++ /dev/null @@ -1,865 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Xml; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Summary description for CloudTableClientTests - /// - [TestClass] - public class CloudTableClientTests : TableTestBase - { - #region Locals + Ctors - public CloudTableClientTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // 20 random tables - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(GenerateRandomTableName()); - tableRef.CreateIfNotExists(); - createdTables.Add(tableRef); - } - - prefixTablesPrefix = "prefixtable" + GenerateRandomTableName(); - // 20 tables with known prefix - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(prefixTablesPrefix + m.ToString()); - tableRef.CreateIfNotExists(); - createdTables.Add(tableRef); - } - } - - private static string prefixTablesPrefix = null; - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - foreach (CloudTable t in createdTables) - { - try - { - t.DeleteIfExists(); - } - catch (Exception) - { - } - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Ctor Test - - [TestMethod] - [Description("Test whether we can create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - CloudTableClient tableClient = new CloudTableClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(tableClient.BaseUri.ToString().Contains(TestBase.TargetTenantConfig.TableServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, tableClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, tableClient.AuthenticationScheme); - - CloudTableClient tableClient2 = new CloudTableClient(baseAddressUri); - Assert.IsTrue(tableClient2.BaseUri.ToString().Contains(TestBase.TargetTenantConfig.TableServiceEndpoint)); - Assert.AreEqual(AuthenticationScheme.SharedKey, tableClient2.AuthenticationScheme); - } - - #endregion - - #region List Tables Iterator - - [TestMethod] - [Description("Test List Tables Iterator No Prefix")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesNoPrefix() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Check each created table is present - List retrievedTables = tableClient.ListTables().ToList(); - foreach (CloudTable t in createdTables) - { - Assert.IsNotNull(retrievedTables.Where((tbl) => tbl.Uri == t.Uri).FirstOrDefault()); - } - } - - [TestMethod] - [Description("Test List Tables Iterator With Prefix Basic")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesWithPrefixBasic() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Check each created table is present - List retrievedTables = tableClient.ListTables(prefixTablesPrefix).ToList(); - foreach (CloudTable t in retrievedTables) - { - CloudTable tableref = retrievedTables.Where((tbl) => tbl.Uri == t.Uri).FirstOrDefault(); - Assert.IsNotNull(createdTables.Where((tbl) => tbl.Uri == t.Uri).FirstOrDefault()); - - Assert.AreEqual(tableref.Uri, t.Uri); - } - - Assert.AreEqual(createdTables.Where((tbl) => tbl.Name.StartsWith(prefixTablesPrefix)).Count(), retrievedTables.Count()); - } - - [TestMethod] - [Description("Test List Tables Iterator With Prefix Extended, will check a variety of ")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesWithPrefixExtended() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - int NumTables = 50; - int TableNameLength = 8; - int NumQueries = 100; - string alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - string numerics = "0123456789"; - string legalChars = alpha + numerics; - - string queryString = string.Empty; - List tableList = new List(); - List localTestCreatedTableList = new List(); - - Random rand = new Random(); - - try - { - #region Generate Tables - - // Generate Tables in Storage - // This will generate all caps Tables, i.e. AAAAAAAA, BBBBBBBB.... - for (int h = 26; h < alpha.Length; h++) - { - string tString = string.Empty; - for (int i = 0; i < TableNameLength; i++) - { - tString += alpha[h]; - } - - CloudTable table = tableClient.GetTableReference(tString); - - if (table.CreateIfNotExists()) - { - tableList.Add(table); - localTestCreatedTableList.Add(table); - } - } - - // Generate some random tables of TableNameLength, table must start with a letter - for (int m = 0; m < NumTables; m++) - { - string tableName = GenerateRandomStringFromCharset(1, alpha, rand).ToLower() + - GenerateRandomStringFromCharset(TableNameLength - 1, legalChars, rand).ToLower(); - - CloudTable table = tableClient.GetTableReference(tableName); - - if (table.CreateIfNotExists()) - { - tableList.Add(table); - localTestCreatedTableList.Add(table); - } - } - - #endregion - - #region Generate Query Strings to cover all boundary conditions - List queryStrings = new List() { String.Empty, "aa", "zz", "az", "Az", "Aa", "zZ", "AA", "ZZ", "AZ", "z9", "a9", "aaa" }; - for (int k = 0; k < legalChars.Length; k++) - { - queryStrings.Add(legalChars[k].ToString()); - } - - for (int n = 0; n <= NumQueries; n++) - { - queryStrings.Add(GenerateRandomStringFromCharset((n % TableNameLength) + 1, legalChars, rand)); - } - #endregion - - #region Merge Created Tables With Pre-existing ones - int totalTables = 0; - foreach (CloudTable listedTable in tableClient.ListTables()) - { - totalTables++; - if (tableList.Where((tbl) => tbl.Uri == listedTable.Uri).FirstOrDefault() != null) - { - continue; - } - - tableList.Add(listedTable); - } - - Assert.AreEqual(tableList.Count, totalTables); - #endregion - - List serviceResult = null; - List LINQResult = null; - - try - { - foreach (string queryValue in queryStrings) - { - queryString = queryValue; - - serviceResult = tableClient.ListTables(queryString).OrderBy((table) => table.Name).ToList(); - LINQResult = tableList.Where((table) => table.Name.ToLower().StartsWith(queryString.ToLower())).OrderBy((table) => table.Name).ToList(); - - Assert.AreEqual(serviceResult.Count(), LINQResult.Count()); - - for (int listDex = 0; listDex < serviceResult.Count(); listDex++) - { - Assert.AreEqual(serviceResult[listDex].Name, LINQResult[listDex].Name); - } - } - } - catch (Exception) - { - // On exception log table names for repro - this.testContextInstance.WriteLine("Exception in ListTablesWithPrefix, Dumping Tables for repro. QueryString = {0}\r\n", queryString); - - foreach (CloudTable table in tableList) - { - this.testContextInstance.WriteLine(table.Name); - } - - this.testContextInstance.WriteLine("Linq results ======================="); - - foreach (CloudTable table in LINQResult) - { - this.testContextInstance.WriteLine(table.Name); - } - - this.testContextInstance.WriteLine("Service results ======================="); - - foreach (CloudTable table in serviceResult) - { - this.testContextInstance.WriteLine(table.Name); - } - throw; - } - } - finally - { - // Cleanup - foreach (CloudTable table in localTestCreatedTableList) - { - // Dont delete Class level tables - if (createdTables.Where((tbl) => tbl.Uri == table.Uri).FirstOrDefault() != null) - { - continue; - } - - // Delete other tables - table.DeleteIfExists(); - } - } - } - - [TestMethod] - [Description("Test List Tables Iterator using Shared Key Lite")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableClientListTablesSharedKeyLite() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - IEnumerable actual = tableClient.ListTables(); - Assert.IsNotNull(actual); - - List retrievedTables = actual.ToList(); - Assert.IsTrue(retrievedTables.Count >= createdTables.Count); - - foreach (CloudTable createdTable in createdTables) - { - Assert.IsNotNull(retrievedTables.Where((t) => t.Uri == createdTable.Uri).FirstOrDefault()); - } - } - - #endregion - - #region List Tables Segmented - - #region Sync - - [TestMethod] - [Description("Verify GetSchema, WriteXml and ReadXml on TableContinuationToken")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableContinuationTokenVerifyXmlFunctions() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - TableContinuationToken token = null; - do - { - segment = tableClient.ListTablesSegmented("prefixtable", 5, segment != null ? segment.ContinuationToken : null); - totalResults.AddRange(segment); - token = segment.ContinuationToken; - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - token.WriteXml(writer); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new TableContinuationToken(); - token.ReadXml(reader); - } - } - } - while (token != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables("prefixtable").Count()); - } - - [TestMethod] - [Description("Verify WriteXml and ReadXml on TableContinuationToken within another XML")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableContinuationTokenVerifyXmlWithinXml() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - TableContinuationToken token = null; - do - { - segment = tableClient.ListTablesSegmented("prefixtable", 5, segment != null ? segment.ContinuationToken : null); - totalResults.AddRange(segment); - token = segment.ContinuationToken; - if (token != null) - { - Assert.AreEqual(null, token.GetSchema()); - - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; - StringBuilder sb = new StringBuilder(); - using (XmlWriter writer = XmlWriter.Create(sb, settings)) - { - writer.WriteStartElement("test1"); - writer.WriteStartElement("test2"); - token.WriteXml(writer); - writer.WriteEndElement(); - writer.WriteEndElement(); - } - - using (XmlReader reader = XmlReader.Create(new StringReader(sb.ToString()))) - { - token = new TableContinuationToken(); - reader.ReadStartElement(); - reader.ReadStartElement(); - token.ReadXml(reader); - reader.ReadEndElement(); - reader.ReadEndElement(); - } - } - } - while (token != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables("prefixtable").Count()); - } - - [TestMethod] - [Description("Test List Tables Segmented Basic Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedBasicSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - do - { - segment = tableClient.ListTablesSegmented(segment != null ? segment.ContinuationToken : null); - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - } - - [TestMethod] - [Description("Test List Tables Segmented MaxResults Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedMaxResultsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = tableClient.ListTablesSegmented(string.Empty, 10, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - Assert.IsTrue(segCount >= totalResults.Count / 10); - } - - [TestMethod] - [Description("Test List Tables Segmented With Prefix Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedWithPrefixSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = tableClient.ListTablesSegmented(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, 20); - foreach (CloudTable tbl in totalResults) - { - Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); - } - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test List Tables Segmented Basic APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedBasicAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - do - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = tableClient.BeginListTablesSegmented(segment != null ? segment.ContinuationToken : null, - (res) => - { - evt.Set(); - }, - null); - - evt.WaitOne(); - - segment = tableClient.EndListTablesSegmented(asyncRes); - } - - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - } - - [TestMethod] - [Description("Test List Tables Segmented MaxResults APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedMaxResultsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = tableClient.BeginListTablesSegmented(string.Empty, - 10, - segment != null ? segment.ContinuationToken : null, - null, - null, - (res) => - { - evt.Set(); - }, - null); - - evt.WaitOne(); - - segment = tableClient.EndListTablesSegmented(asyncRes); - } - - Assert.IsTrue(segment.Count() <= 10); - - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - Assert.IsTrue(segCount >= totalResults.Count / 10); - } - - [TestMethod] - [Description("Test List Tables Segmented With Prefix APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedWithPrefixAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = tableClient.BeginListTablesSegmented(prefixTablesPrefix, - null, - segment != null ? segment.ContinuationToken : null, - null, - null, - (res) => - { - evt.Set(); - }, - null); - - evt.WaitOne(); - - segment = tableClient.EndListTablesSegmented(asyncRes); - } - - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, 20); - foreach (CloudTable tbl in totalResults) - { - Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); - } - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableContinuationToken token = null; - - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(token).Result; - token = resultSegment.ContinuationToken; - } - while (token != null); - } - - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedPrefixTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string prefix = prefixTablesPrefix; - TableContinuationToken token = null; - - int totalCount = 0; - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(prefix, token).Result; - token = resultSegment.ContinuationToken; - - foreach (CloudTable table in resultSegment) - { - Assert.IsTrue(table.Name.StartsWith(prefix)); - ++totalCount; - } - } - while (token != null); - - Assert.AreEqual(20, totalCount); - } - - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedTokenCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(token, cancellationToken).Result; - token = resultSegment.ContinuationToken; - } - while (token != null); - } - - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedPrefixTokenCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string prefix = prefixTablesPrefix; - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - int totalCount = 0; - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(prefix, token, cancellationToken).Result; - token = resultSegment.ContinuationToken; - - foreach (CloudTable table in resultSegment) - { - Assert.IsTrue(table.Name.StartsWith(prefix)); - ++totalCount; - } - } - while (token != null); - - Assert.AreEqual(20, totalCount); - } - - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedPrefixMaxResultsTokenRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string prefix = prefixTablesPrefix; - int? maxResults = 10; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - int totalCount = 0; - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(prefix, maxResults, token, requestOptions, operationContext).Result; - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudTable table in resultSegment) - { - Assert.IsTrue(table.Name.StartsWith(prefix)); - ++count; - } - - totalCount += count; - - Assert.IsTrue(count <= maxResults.Value); - } - while (token != null); - - Assert.AreEqual(20, totalCount); - } - - [TestMethod] - [Description("Test TableClient ListTablesSegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ListTablesSegmentedPrefixMaxResultsTokenRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string prefix = prefixTablesPrefix; - int? maxResults = 10; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - int totalCount = 0; - do - { - TableResultSegment resultSegment = tableClient.ListTablesSegmentedAsync(prefix, maxResults, token, requestOptions, operationContext, cancellationToken).Result; - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudTable table in resultSegment) - { - Assert.IsTrue(table.Name.StartsWith(prefix)); - ++count; - } - - totalCount += count; - - Assert.IsTrue(count <= maxResults.Value); - } - while (token != null); - - Assert.AreEqual(20, totalCount); - } -#endif - - #endregion - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/InternalEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/InternalEntity.cs deleted file mode 100644 index 0e6eebf937129..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/InternalEntity.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - internal class InternalEntity : TableEntity - { - public InternalEntity() - { - } - - public InternalEntity(string pk, string rk) - : base(pk, rk) - { - } - - public void Populate() - { - this.foo = "bar"; - this.A = "a"; - this.B = "b"; - this.C = "c"; - this.D = "d"; - } - - public string foo { get; set; } - public string A { get; set; } - public string B { get; set; } - public string C { get; set; } - public string D { get; set; } - - public void Validate() - { - Assert.AreEqual(this.foo, "bar"); - Assert.AreEqual(this.A, "a"); - Assert.AreEqual(this.B, "b"); - Assert.AreEqual(this.C, "c"); - Assert.AreEqual(this.D, "d"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/NoCtorEntity.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/NoCtorEntity.cs deleted file mode 100644 index b5eb9fec34712..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/Entities/NoCtorEntity.cs +++ /dev/null @@ -1,37 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif -namespace Microsoft.WindowsAzure.Storage.Table.Entities -{ - internal class NoCtorEntity : TableEntity - { - public NoCtorEntity(string foo) - { - } - - public string foo { get; set; } - public string A { get; set; } - public string B { get; set; } - public string C { get; set; } - public string D { get; set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasFunctionalTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasFunctionalTests.cs deleted file mode 100644 index 5d931ad0ef4a4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasFunctionalTests.cs +++ /dev/null @@ -1,473 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table.SAS -{ - [TestClass] - public class TableSasFunctionalTests : TableTestBase - { - #region Locals + Ctors - public TableSasFunctionalTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Permissions - - [TestMethod] - // [Description("Tests setting and getting table permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetPermissionTestSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - table.Create(); - - table.Execute(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions; - TablePermissions testPermissions; - - // Test new table permissions. - expectedPermissions = new TablePermissions(); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Test setting empty permissions. - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a null policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.None, - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromDays(0.5), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Update, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(6), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(6.5) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - -#if TASK - [TestMethod] - [Description("Test Table GetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetPermissionsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - TablePermissions expected = new TablePermissions(); - TablePermissions actual = table.GetPermissionsAsync().Result; - AssertPermissionsEqual(expected, actual); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table GetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetPermissionsCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - TablePermissions expected = new TablePermissions(); - TablePermissions actual = table.GetPermissionsAsync(cancellationToken).Result; - AssertPermissionsEqual(expected, actual); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table GetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetPermissionsRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - TablePermissions expected = new TablePermissions(); - TablePermissions actual = table.GetPermissionsAsync(requestOptions, operationContext).Result; - AssertPermissionsEqual(expected, actual); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table GetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetPermissionsRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - TablePermissions expected = new TablePermissions(); - TablePermissions actual = table.GetPermissionsAsync(requestOptions, operationContext, cancellationToken).Result; - AssertPermissionsEqual(expected, actual); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table SetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetPermissionsPermissionsTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TablePermissions permissions = new TablePermissions(); - - permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy() - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now.Add(new TimeSpan(-1, 0, 0)), - SharedAccessExpiryTime = DateTimeOffset.Now.Add(new TimeSpan(1, 0, 0)) - }); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - table.SetPermissionsAsync(permissions); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table SetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetPermissionsPermissionsCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TablePermissions permissions = new TablePermissions(); - CancellationToken cancellationToken = CancellationToken.None; - - permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy() - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now.Add(new TimeSpan(-1, 0, 0)), - SharedAccessExpiryTime = DateTimeOffset.Now.Add(new TimeSpan(1, 0, 0)) - }); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - table.SetPermissionsAsync(permissions, cancellationToken); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table SetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetPermissionsPermissionsRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TablePermissions permissions = new TablePermissions(); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy() - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now.Add(new TimeSpan(-1, 0, 0)), - SharedAccessExpiryTime = DateTimeOffset.Now.Add(new TimeSpan(1, 0, 0)) - }); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - table.SetPermissionsAsync(permissions, requestOptions, operationContext); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table SetPermissions - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetPermissionsPermissionsRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable table = tableClient.GetTableReference(tableName); - TablePermissions permissions = new TablePermissions(); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - permissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy() - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now.Add(new TimeSpan(-1, 0, 0)), - SharedAccessExpiryTime = DateTimeOffset.Now.Add(new TimeSpan(1, 0, 0)) - }); - - try - { - table.CreateAsync().Wait(); - table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))).Wait(); - - table.SetPermissionsAsync(permissions, requestOptions, operationContext, cancellationToken); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } -#endif - - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasUnitTests.cs deleted file mode 100644 index e16658bcdcdd3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/SAS/TableSasUnitTests.cs +++ /dev/null @@ -1,1139 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableSasUnitTests : TableTestBase - { - #region Locals + Ctors - public TableSasUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - // - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Constructor Tests - - [TestMethod] - [Description("Test TableSas via various constructors")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSASConstructors() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - table.Create(); - - table.Execute(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - // Prepare SAS authentication with full permissions - string sasToken = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null /* accessPolicyIdentifier */, - null /* startPk */, - null /* startRk */, - null /* endPk */, - null /* endRk */); - - CloudStorageAccount sasAccount; - StorageCredentials sasCreds; - CloudTableClient sasClient; - CloudTable sasTable; - Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - - // SAS via connection string parse - sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken)); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - - Assert.AreEqual(1, sasTable.ExecuteQuery(new TableQuery()).Count()); - - // SAS via account constructor - sasCreds = new StorageCredentials(sasToken); - sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - Assert.AreEqual(1, sasTable.ExecuteQuery(new TableQuery()).Count()); - - // SAS via client constructor URI + Creds - sasCreds = new StorageCredentials(sasToken); - sasClient = new CloudTableClient(baseUri, sasCreds); - Assert.AreEqual(1, sasTable.ExecuteQuery(new TableQuery()).Count()); - - // SAS via CloudTable constructor Uri + Client - sasCreds = new StorageCredentials(sasToken); - sasTable = new CloudTable(table.Uri, tableClient.Credentials); - sasClient = sasTable.ServiceClient; - Assert.AreEqual(1, sasTable.ExecuteQuery(new TableQuery()).Count()); - } - finally - { - table.DeleteIfExists(); - } - } - - #endregion - - #region Permissions - - [TestMethod] - [Description("Tests setting and getting table permissions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSetGetPermissions() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - table.Execute(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = table.GetPermissions(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - testPermissions = table.GetPermissions(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExists(); - } - } - - - [TestMethod] - [Description("Tests Null Access Policy")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSASNullAccessPolicy() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - table.Execute(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions = new TablePermissions(); - - // Add a policy - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Add, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - table.SetPermissions(expectedPermissions); - Thread.Sleep(30 * 1000); - - // Generate the sasToken the user should use - string sasToken = table.GetSharedAccessSignature(null, expectedPermissions.SharedAccessPolicies.First().Key, "AAAA", null, "AAAA", null); - - CloudTable sasTable = new CloudTable(table.Uri, new StorageCredentials(sasToken)); - - sasTable.Execute(TableOperation.Insert(new DynamicTableEntity("AAAA", "foo"))); - - TableResult result = sasTable.Execute(TableOperation.Retrieve("AAAA", "foo")); - - Assert.IsNotNull(result.Result); - - // revoke table permissions - table.SetPermissions(new TablePermissions()); - Thread.Sleep(30 * 1000); - - OperationContext opContext = new OperationContext(); - try - { - sasTable.Execute(TableOperation.Insert(new DynamicTableEntity("AAAA", "foo2")), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(opContext.LastResult.HttpStatusCode, (int)HttpStatusCode.Forbidden); - } - - opContext = new OperationContext(); - try - { - result = sasTable.Execute(TableOperation.Retrieve("AAAA", "foo"), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(opContext.LastResult.HttpStatusCode, (int)HttpStatusCode.Forbidden); - } - } - finally - { - table.DeleteIfExists(); - } - } - #endregion - - #region SAS Operations - - [TestMethod] - [Description("Tests table SAS with query permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasQueryTestSync() - { - TestTableSas(SharedAccessTablePermissions.Query); - } - - [TestMethod] - [Description("Tests table SAS with delete permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasDeleteTestSync() - { - TestTableSas(SharedAccessTablePermissions.Delete); - } - - [TestMethod] - [Description("Tests table SAS with process and update permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasUpdateTestSync() - { - TestTableSas(SharedAccessTablePermissions.Update); - } - - [TestMethod] - [Description("Tests table SAS with add permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasAddTestSync() - { - TestTableSas(SharedAccessTablePermissions.Add); - } - - [TestMethod] - [Description("Tests table SAS with full permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasFullTestSync() - { - TestTableSas(SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// Various table range constraints are tested. - /// - /// The permissions to test. - internal void TestTableSas(SharedAccessTablePermissions accessPermissions) - { - string startPk = "M"; - string startRk = "F"; - string endPk = "S"; - string endRk = "T"; - - // No ranges specified - TestTableSasWithRange(accessPermissions, null, null, null, null); - - // All ranges specified - TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, endRk); - - // StartPk & StartRK specified - TestTableSasWithRange(accessPermissions, startPk, startRk, null, null); - - // StartPk specified - TestTableSasWithRange(accessPermissions, startPk, null, null, null); - - // EndPk & EndRK specified - TestTableSasWithRange(accessPermissions, null, null, endPk, endRk); - - // EndPk specified - TestTableSasWithRange(accessPermissions, null, null, endPk, null); - - // StartPk and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, null, endPk, null); - - // StartRk and StartRK and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, null); - - // StartRk and EndPK and EndPk specified - TestTableSasWithRange(accessPermissions, startPk, null, endPk, endRk); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// - /// The permissions to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - internal void TestTableSasWithRange( - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - // Set up a policy - string identifier = Guid.NewGuid().ToString(); - TablePermissions permissions = new TablePermissions(); - permissions.SharedAccessPolicies.Add(identifier, new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddDays(1) - }); - - table.SetPermissions(permissions); - Thread.Sleep(30 * 1000); - - // Prepare SAS authentication using access identifier - string sasString = table.GetSharedAccessSignature(new SharedAccessTablePolicy(), identifier, startPk, startRk, endPk, endRk); - CloudTableClient identifierSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Prepare SAS authentication using explicit policy - sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null, - startPk, - startRk, - endPk, - endRk); - - CloudTableClient explicitSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Point query - TestPointQuery(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestPointQuery(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Add row - TestAdd(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestAdd(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (merge) - TestUpdateMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpdateMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (replace) - TestUpdateReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpdateReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Delete row - TestDelete(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestDelete(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (merge) - TestUpsertMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpsertMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (replace) - TestUpsertReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - TestUpsertReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - } - finally - { - table.DeleteIfExists(); - } - } - - - /// - /// Test point queries entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestPointQuery( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Query) != 0; - - Action queryDelegate = (tableEntity, ctx) => - { - TableResult retrieveResult = testClient.GetTableReference(tableName).Execute(TableOperation.Retrieve(tableEntity.PartitionKey, tableEntity.RowKey), null, ctx); - - if (expectSuccess) - { - Assert.IsNotNull(retrieveResult.Result); - } - else - { - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.OK); - } - }; - - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - queryDelegate, - "point query", - expectSuccess, - expectSuccess ? HttpStatusCode.OK : HttpStatusCode.NotFound); - } - - - /// - /// Test update (merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpdateMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity, ctx) => - { - // Merge entity - tableEntity.A = "10"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).Execute(TableOperation.Merge(tableEntity), null, ctx); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test update (replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpdateReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity, ctx) => - { - // replace entity - tableEntity.A = "20"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).Execute(TableOperation.Replace(tableEntity), null, ctx); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test adding entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestAdd( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action addDelegate = (tableEntity, ctx) => - { - // insert entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).Execute(TableOperation.Insert(tableEntity), null, ctx); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Add) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - addDelegate, - "add", - expectSuccess, - expectSuccess ? HttpStatusCode.Created : HttpStatusCode.NotFound); - } - - /// - /// Test deleting entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestDelete( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action deleteDelegate = (tableEntity, ctx) => - { - // delete entity - tableEntity.A = "10"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).Execute(TableOperation.Delete(tableEntity), null, ctx); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Delete) != 0; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - deleteDelegate, - "delete", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpsertMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity, ctx) => - { - // insert or merge entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).Execute(TableOperation.InsertOrMerge(tableEntity), null, ctx); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private void TestUpsertReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity, ctx) => - { - // insert or replace entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).Execute(TableOperation.InsertOrReplace(tableEntity), null, ctx); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private void TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode) - { - TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - runOperationDelegate, - opName, - expectSuccess, - expectedStatusCode, - false /* isRangeQuery */); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private void TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode, - bool isRangeQuery) - { - CloudTableClient referenceClient = GenerateCloudTableClient(); - - string partitionKey = startPk ?? endPk ?? "M"; - string rowKey = startRk ?? endRk ?? "S"; - - // if we expect a success for creation - avoid inserting duplicate entities - BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey); - if (expectedStatusCode == HttpStatusCode.Created) - { - try - { - tableEntity.ETag = "*"; - referenceClient.GetTableReference(tableName).Execute(TableOperation.Delete(tableEntity)); - } - catch (Exception) - { - } - } - else - { - // only for add we should not be adding the entity - referenceClient.GetTableReference(tableName).Execute(TableOperation.InsertOrReplace(tableEntity)); - } - - if (expectSuccess) - { - runOperationDelegate(tableEntity, null); - } - else - { - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} without appropriate permission.", opName), - (int)HttpStatusCode.NotFound); - } - - if (startPk != null) - { - tableEntity.PartitionKey = "A"; - if (startPk.CompareTo(tableEntity.PartitionKey) <= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} before allowed partition key range", opName), - (int)HttpStatusCode.NotFound); - tableEntity.PartitionKey = partitionKey; - } - - if (endPk != null) - { - tableEntity.PartitionKey = "Z"; - if (endPk.CompareTo(tableEntity.PartitionKey) >= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} after allowed partition key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.PartitionKey = partitionKey; - } - - if (startRk != null) - { - if (isRangeQuery || startPk != null) - { - tableEntity.PartitionKey = startPk; - tableEntity.RowKey = "A"; - if (startRk.CompareTo(tableEntity.RowKey) <= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} before allowed row key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - - if (endRk != null) - { - if (isRangeQuery || endPk != null) - { - tableEntity.PartitionKey = endPk; - tableEntity.RowKey = "Z"; - if (endRk.CompareTo(tableEntity.RowKey) >= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} after allowed row key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - } - #endregion - - #region SAS Error Conditions - - //[TestMethod] // Disabled until service bug is fixed - [Description("Attempt to use SAS to authenticate table operations that must not work with SAS.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasInvalidOperations() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - // Prepare SAS authentication with full permissions - string sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete, - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30) - }, - null, - null, - null, - null, - null); - - CloudTableClient sasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Construct a valid set of service properties to upload. - ServiceProperties properties = new ServiceProperties(); - properties.Logging.Version = "1.0"; - properties.Metrics.Version = "1.0"; - properties.Logging.RetentionDays = 9; - sasClient.GetServiceProperties(); - sasClient.SetServiceProperties(properties); - - // Test invalid client operations - // BUGBUG: ListTables hides the exception. We should fix this - // TestHelpers.ExpectedException(() => sasClient.ListTablesSegmented(), "List tables with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasClient.GetServiceProperties(), "Get service properties with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasClient.SetServiceProperties(properties), "Set service properties with SAS", (int)HttpStatusCode.NotFound); - - CloudTable sasTable = sasClient.GetTableReference(table.Name); - - // Verify that creation fails with SAS - TestHelper.ExpectedException((ctx) => sasTable.Create(null, ctx), "Create a table with SAS", (int)HttpStatusCode.NotFound); - - // Create the table. - table.Create(); - - // Test invalid table operations - TestHelper.ExpectedException((ctx) => sasTable.Delete(null, ctx), "Delete a table with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasTable.GetPermissions(null, ctx), "Get ACL with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasTable.SetPermissions(new TablePermissions(), null, ctx), "Set ACL with SAS", (int)HttpStatusCode.NotFound); - } - finally - { - table.DeleteIfExists(); - } - } - - #endregion - - #region Update SAS token - [TestMethod] - [Description("Update table SAS.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableUpdateSasTestSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - BaseEntity entity = new BaseEntity("PK", "RK"); - table.Execute(TableOperation.Insert(entity)); - - SharedAccessTablePolicy policy = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete, - }; - - string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null); - StorageCredentials creds = new StorageCredentials(sasToken); - CloudTable sasTable = new CloudTable(table.Uri, creds); - TestHelper.ExpectedException( - () => sasTable.Execute(TableOperation.Insert(new BaseEntity("PK", "RK2"))), - "Try to insert an entity when SAS doesn't allow inserts", - HttpStatusCode.NotFound); - - sasTable.Execute(TableOperation.Delete(entity)); - - SharedAccessTablePolicy policy2 = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, - }; - - string sasToken2 = table.GetSharedAccessSignature(policy2, null, null, null, null, null); - creds.UpdateSASToken(sasToken2); - - sasTable = new CloudTable(table.Uri, creds); - - sasTable.Execute(TableOperation.Insert(new BaseEntity("PK", "RK2"))); - - } - finally - { - table.DeleteIfExists(); - } - } - #endregion - - #region SasUri - [TestMethod] - [Description("Use table SasUri.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableSasUriTestSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - table.Create(); - - BaseEntity entity = new BaseEntity("PK", "RK"); - BaseEntity entity1 = new BaseEntity("PK", "RK1"); - table.Execute(TableOperation.Insert(entity)); - table.Execute(TableOperation.Insert(entity1)); - - SharedAccessTablePolicy policy = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete, - }; - - string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null); - StorageCredentials creds = new StorageCredentials(sasToken); - CloudStorageAccount sasAcc = new CloudStorageAccount(creds, new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint), new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint), new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint)); - CloudTableClient client = sasAcc.CreateCloudTableClient(); - - CloudTable sasTable = new CloudTable(client.Credentials.TransformUri(table.Uri)); - sasTable.Execute(TableOperation.Delete(entity)); - - CloudTable sasTable2 = new CloudTable(new Uri(table.Uri.ToString() + sasToken)); - sasTable2.Execute(TableOperation.Delete(entity1)); - } - finally - { - table.DeleteIfExists(); - } - } - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableAnalyticsUnitTests.cs deleted file mode 100644 index ec5354cb9ade5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableAnalyticsUnitTests.cs +++ /dev/null @@ -1,526 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableAnalyticsUnitTests : TableTestBase - { - #region Locals + Ctors - public TableAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - startProperties = tableClient.GetServiceProperties(); - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.SetServiceProperties(startProperties); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - #endregion - - #region Analytics RoundTrip - - #region Sync - - [TestMethod] - [Description("Test Analytics Round Trip Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsRoundTripSync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - #endregion - - #region APM - - [TestMethod] - [Description("Test Analytics Round Trip APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsRoundTripAPM() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginSetServiceProperties(props, (res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - client.EndSetServiceProperties(result); - } - - ServiceProperties retrievedProps = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult result = null; - client.BeginGetServiceProperties((res) => - { - result = res; - evt.Set(); - }, null); - evt.WaitOne(); - - retrievedProps = client.EndGetServiceProperties(result); - } - - AssertServicePropertiesAreEqual(props, retrievedProps); - } - - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("Test Analytics Round Trip Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsRoundTripTask() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - client.SetServicePropertiesAsync(props).Wait(); - - AssertServicePropertiesAreEqual(props, client.GetServicePropertiesAsync().Result); - } - - [TestMethod] - [Description("Test Table GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetServicePropertiesTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 8; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 8; - serviceProperties.Metrics.Version = "1.0"; - - tableClient.SetServicePropertiesAsync(serviceProperties).Wait(); - - ServiceProperties actual = tableClient.GetServicePropertiesAsync().Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Table GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetServicePropertiesCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CancellationToken cancellationToken = CancellationToken.None; - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 9; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 9; - serviceProperties.Metrics.Version = "1.0"; - - tableClient.SetServicePropertiesAsync(serviceProperties, cancellationToken).Wait(); - - ServiceProperties actual = tableClient.GetServicePropertiesAsync(cancellationToken).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Table GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetServicePropertiesRequestOptionsOperationContextTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 10; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 10; - serviceProperties.Metrics.Version = "1.0"; - - tableClient.SetServicePropertiesAsync(serviceProperties, requestOptions, operationContext).Wait(); - - ServiceProperties actual = tableClient.GetServicePropertiesAsync(requestOptions, operationContext).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } - - [TestMethod] - [Description("Test Table GetServiceProperties and SetServiceProperties - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGetSetServicePropertiesRequestOptionsOperationContextCancellationTokenTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - ServiceProperties serviceProperties = new ServiceProperties(); - serviceProperties.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write | LoggingOperations.Delete; - serviceProperties.Logging.RetentionDays = 11; - serviceProperties.Logging.Version = "1.0"; - serviceProperties.Metrics.MetricsLevel = MetricsLevel.Service; - serviceProperties.Metrics.RetentionDays = 11; - serviceProperties.Metrics.Version = "1.0"; - - tableClient.SetServicePropertiesAsync(serviceProperties, requestOptions, operationContext, cancellationToken).Wait(); - - ServiceProperties actual = tableClient.GetServicePropertiesAsync(requestOptions, operationContext, cancellationToken).Result; - - AssertServicePropertiesAreEqual(serviceProperties, actual); - } -#endif - - #endregion - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsDisable() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsDefaultServiceVersionThrows() - { - CloudTableClient client = GenerateCloudTableClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - client.SetServiceProperties(props, null, ctx); - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - catch (StorageException ex) - { - Assert.AreEqual(ex.Message, "The remote server returned an error: (400) Bad Request."); - Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsLoggingOperations() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsMetricsLevel() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableTestAnalyticsRetentionPolicies() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = client.GetServiceProperties(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - client.SetServiceProperties(props); - - AssertServicePropertiesAreEqual(props, client.GetServiceProperties()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableBatchOperationTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableBatchOperationTest.cs deleted file mode 100644 index aa347454aa2d9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableBatchOperationTest.cs +++ /dev/null @@ -1,2641 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableBatchOperationTest : TableTestBase - { - #region Locals + Ctors - public TableBatchOperationTest() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Insert - - #region Sync - [TestMethod] - [Description("A test to check the DynamicTableEntity constructor")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableDynamicTableEntityConstructor() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - Dictionary properties = new Dictionary(); - properties.Add("foo", new EntityProperty("bar")); - properties.Add("foo1", new EntityProperty("bar1")); - - DynamicTableEntity ent = new DynamicTableEntity(pk, rk, "*", properties); - currentTable.Execute(TableOperation.Insert(ent)); - } - - [TestMethod] - [Description("A test to check the DynamicTableEntity setter")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableDynamicTableEntitySetter() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - Dictionary properties = new Dictionary(); - properties.Add("foo", new EntityProperty("bar")); - properties.Add("foo1", new EntityProperty("bar1")); - - DynamicTableEntity ent = new DynamicTableEntity(); - ent.PartitionKey = pk; - ent.RowKey = rk; - ent.Properties = properties; - ent.ETag = "*"; - ent.Timestamp = DateTimeOffset.MinValue; - currentTable.Execute(TableOperation.Insert(ent)); - } - - [TestMethod] - [Description("A test to check EntityProperty")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEntityPropertyGenerator() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - Dictionary properties = new Dictionary(); - EntityProperty boolEntity = EntityProperty.GeneratePropertyForBool(true); - properties.Add("boolEntity", boolEntity); - EntityProperty timeEntity = EntityProperty.GeneratePropertyForDateTimeOffset(DateTimeOffset.UtcNow); - properties.Add("timeEntity", timeEntity); - EntityProperty doubleEntity = EntityProperty.GeneratePropertyForDouble(0.1); - properties.Add("doubleEntity", doubleEntity); - EntityProperty guidEntity = EntityProperty.GeneratePropertyForGuid(Guid.NewGuid()); - properties.Add("guidEntity", guidEntity); - EntityProperty intEntity = EntityProperty.GeneratePropertyForInt(1); - properties.Add("intEntity", intEntity); - EntityProperty longEntity = EntityProperty.GeneratePropertyForLong(1); - properties.Add("longEntity", longEntity); - EntityProperty stringEntity = EntityProperty.GeneratePropertyForString("string"); - properties.Add("stringEntity", stringEntity); - - DynamicTableEntity ent = new DynamicTableEntity(pk, rk, "*", properties); - currentTable.Execute(TableOperation.Insert(ent)); - } - - [TestMethod] - [Description("A test to check EntityProperty setter")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEntityPropertySetter() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - Dictionary properties = new Dictionary(); - EntityProperty boolEntity = EntityProperty.GeneratePropertyForBool(null); - boolEntity.BooleanValue = true; - properties.Add("boolEntity", boolEntity); - - EntityProperty timeEntity = EntityProperty.GeneratePropertyForDateTimeOffset(null); - timeEntity.DateTimeOffsetValue = DateTimeOffset.UtcNow; - properties.Add("timeEntity", timeEntity); - - EntityProperty doubleEntity = EntityProperty.GeneratePropertyForDouble(null); - doubleEntity.DoubleValue = 0.1; - properties.Add("doubleEntity", doubleEntity); - - EntityProperty guidEntity = EntityProperty.GeneratePropertyForGuid(null); - guidEntity.GuidValue = Guid.NewGuid(); - properties.Add("guidEntity", guidEntity); - - EntityProperty intEntity = EntityProperty.GeneratePropertyForInt(null); - intEntity.Int32Value = 1; - properties.Add("intEntity", intEntity); - - EntityProperty longEntity = EntityProperty.GeneratePropertyForLong(null); - longEntity.Int64Value = 1; - properties.Add("longEntity", longEntity); - - EntityProperty stringEntity = EntityProperty.GeneratePropertyForString(null); - stringEntity.StringValue = "string"; - properties.Add("stringEntity", stringEntity); - - DynamicTableEntity ent = new DynamicTableEntity(pk, rk, "*", properties); - currentTable.Execute(TableOperation.Insert(ent)); - } - - [TestMethod] - [Description("A test to check batch insert functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertSync() - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 3; m++) - { - AddInsertToBatch(pk, batch); - } - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - currentTable.Execute(TableOperation.Insert(ent)); - - // Add delete - batch.Delete(ent); - - IList results = currentTable.ExecuteBatch(batch); - - Assert.AreEqual(results.Count, 4); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - // delete - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - [TestMethod] - [Description("A test to check batch basic functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchBasicOperationsCheck() - { - string pk = Guid.NewGuid().ToString(); - TableBatchOperation batch = new TableBatchOperation(); - - // Add insert - DynamicTableEntity ent1 = GenerateRandomEnitity(pk); - TableOperation operation1 = TableOperation.Insert(ent1); - batch.Add(operation1); - - DynamicTableEntity ent2 = GenerateRandomEnitity(pk); - TableOperation operation2 = TableOperation.Insert(ent2); - batch.Add(operation2); - - TableOperation[] operationsArray = new TableOperation[2]; - batch.CopyTo(operationsArray, 0); - - Assert.AreEqual(operation1.Entity.RowKey, operationsArray[0].Entity.RowKey); - Assert.AreEqual(operation1.OperationType, operationsArray[0].OperationType); - Assert.AreEqual(operation2.Entity.RowKey, operationsArray[1].Entity.RowKey); - Assert.AreEqual(operation2.OperationType, operationsArray[1].OperationType); - - Assert.AreEqual(0, batch.IndexOf(operation1)); - Assert.AreEqual(1, batch.IndexOf(operation2)); - - IEnumerator enumerator = batch.GetEnumerator(); - int totalCount = 0; - while (enumerator.MoveNext()) - totalCount++; - Assert.AreEqual(2, totalCount); - - Assert.IsTrue(batch.Remove(operation2)); - Assert.IsFalse(batch.IsReadOnly); - TestHelper.ExpectedException(() => batch[0] = operation1, - "Setter is not supported for TableBatchOperation"); - } - - [TestMethod] - [Description("A test to check batch insert functionality when entity already exists")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertFailSync() - { - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - currentTable.Execute(TableOperation.Insert(ent)); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - - #region APM - [TestMethod] - [Description("A test to check batch insert functionality APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertAPM() - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 3; m++) - { - AddInsertToBatch(pk, batch); - } - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - currentTable.Execute(TableOperation.Insert(ent)); - - // Add delete - batch.Delete(ent); - - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 4); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - // delete - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - [TestMethod] - [Description("A test to check batch insert functionality when entity already exists APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertFailAPM() - { - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - currentTable.Execute(TableOperation.Insert(ent)); - - - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("A test to check batch insert functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertTask() - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 3; m++) - { - AddInsertToBatch(pk, batch); - } - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - currentTable.ExecuteAsync(TableOperation.Insert(ent)).Wait(); - - // Add delete - batch.Delete(ent); - - IList results = currentTable.ExecuteBatchAsync(batch).Result; - - Assert.AreEqual(results.Count, 4); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - // delete - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - [TestMethod] - [Description("A test to check batch insert functionality when entity already exists")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertFailTask() - { - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - currentTable.ExecuteAsync(TableOperation.Insert(ent)).Wait(); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatchAsync(batch, null, opContext).Wait(); - Assert.Fail(); - } - catch (AggregateException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } -#endif - - #endregion - - #endregion - - #region Insert Or Merge - - #region Sync - [TestMethod] - [Description("TableBatch Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMergeSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrMerge(mergeEntity); - currentTable.ExecuteBatch(batch2); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region APM - [TestMethod] - [Description("TableBatch Insert Or Merge APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMergeAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrMerge(mergeEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch2, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - #endregion - - #region Insert Or Replace - - #region Sync - [TestMethod] - [Description("TableOperation Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrReplaceSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrReplace(replaceEntity); - currentTable.ExecuteBatch(batch2); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Insert Or Replace APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrReplaceAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrReplace(replaceEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch2, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - #endregion - #endregion - - #region Delete - - #region Sync - [TestMethod] - [Description("A test to check batch delete functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchDeleteSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(ent)); - - TableBatchOperation batch = new TableBatchOperation(); - - // Add delete - batch.Delete(ent); - - // success - IList results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NoContent); - - // fail - not found - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - [TestMethod] - [Description("A test to check batch delete failure")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchDeleteFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - currentTable.Execute(TableOperation.Insert(ent)); - - // update entity - TableResult res = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEnt = res.Result as DynamicTableEntity; - retrievedEnt.Properties.Add("prop", new EntityProperty("var")); - currentTable.Execute(TableOperation.Replace(retrievedEnt)); - - // Attempt to delete with stale etag - TableBatchOperation batch = new TableBatchOperation(); - batch.Delete(ent); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - #endregion - - #region APM - [TestMethod] - [Description("A test to check batch delete functionalityAPM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchDeleteAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(ent)); - - TableBatchOperation batch = new TableBatchOperation(); - - // Add delete - batch.Delete(ent); - - // success - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NoContent); - - // fail - not found - OperationContext opContext = new OperationContext(); - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - [TestMethod] - [Description("A test to check batch delete failure APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchDeleteFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - currentTable.Execute(TableOperation.Insert(ent)); - - // update entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEnt = result.Result as DynamicTableEntity; - retrievedEnt.Properties.Add("prop", new EntityProperty("var")); - currentTable.Execute(TableOperation.Replace(retrievedEnt)); - - // Attempt to delete with stale etag - TableBatchOperation batch = new TableBatchOperation(); - batch.Delete(ent); - - OperationContext opContext = new OperationContext(); - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - #endregion - - #endregion - - #region Merge - - #region Sync - [TestMethod] - [Description("TableBatch Merge Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchMergeSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Merge Fail Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchMergeFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - currentTable.ExecuteBatch(batch, null, opContext); - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - currentTable.ExecuteBatch(batch, null, opContext); - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region APM - [TestMethod] - [Description("TableBatch Merge APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchMergeAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Merge Fail APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchMergeFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #endregion - - #region Replace - - #region Sync - [TestMethod] - [Description("TableBatch ReplaceSync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchReplaceSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Replace Fail Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchReplaceFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region APM - [TestMethod] - [Description("TableBatch Replace APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchReplaceAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Replace Fail APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchReplaceFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecuteBatch(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #endregion - - #region Batch With All Supported Operations - - #region Sync - [TestMethod] - [Description("A test to check batch with all supported operations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAllSupportedOperationsSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - // insert - batch.Insert(GenerateRandomEnitity(pk)); - - // delete - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Delete(entity); - } - - // replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Replace(entity); - } - - // insert or replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.InsertOrReplace(entity); - } - - // merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Merge(entity); - } - - // insert or merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.InsertOrMerge(entity); - } - - IList results = currentTable.ExecuteBatch(batch); - - Assert.AreEqual(results.Count, 6); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - #endregion - - #region APM - [TestMethod] - [Description("A test to check batch with all supported operations APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAllSupportedOperationsAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - // insert - batch.Insert(GenerateRandomEnitity(pk)); - - // delete - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Delete(entity); - } - - // replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Replace(entity); - } - - // insert or replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.InsertOrReplace(entity); - } - - // merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.Merge(entity); - } - - // insert or merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - currentTable.Execute(TableOperation.Insert(entity)); - batch.InsertOrMerge(entity); - } - - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 6); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - #endregion - #endregion - - #region Retrieve - - #region Sync - [TestMethod] - [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(pk); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt["String"], retrievedEntity["String"]); - Assert.AreEqual(sendEnt["Int64"], retrievedEntity["Int64"]); - Assert.AreEqual(sendEnt["Int64N"], retrievedEntity["Int64N"]); - Assert.AreEqual(sendEnt["LongPrimitive"], retrievedEntity["LongPrimitive"]); - Assert.AreEqual(sendEnt["LongPrimitiveN"], retrievedEntity["LongPrimitiveN"]); - Assert.AreEqual(sendEnt["Int32"], retrievedEntity["Int32"]); - Assert.AreEqual(sendEnt["Int32N"], retrievedEntity["Int32N"]); - Assert.AreEqual(sendEnt["IntegerPrimitive"], retrievedEntity["IntegerPrimitive"]); - Assert.AreEqual(sendEnt["IntegerPrimitiveN"], retrievedEntity["IntegerPrimitiveN"]); - Assert.AreEqual(sendEnt["Guid"], retrievedEntity["Guid"]); - Assert.AreEqual(sendEnt["GuidN"], retrievedEntity["GuidN"]); - Assert.AreEqual(sendEnt["Double"], retrievedEntity["Double"]); - Assert.AreEqual(sendEnt["DoubleN"], retrievedEntity["DoubleN"]); - Assert.AreEqual(sendEnt["DoublePrimitive"], retrievedEntity["DoublePrimitive"]); - Assert.AreEqual(sendEnt["DoublePrimitiveN"], retrievedEntity["DoublePrimitiveN"]); - Assert.AreEqual(sendEnt["BinaryPrimitive"], retrievedEntity["BinaryPrimitive"]); - Assert.AreEqual(sendEnt["Binary"], retrievedEntity["Binary"]); - Assert.AreEqual(sendEnt["BoolPrimitive"], retrievedEntity["BoolPrimitive"]); - Assert.AreEqual(sendEnt["BoolPrimitiveN"], retrievedEntity["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt["Bool"], retrievedEntity["Bool"]); - Assert.AreEqual(sendEnt["BoolN"], retrievedEntity["BoolN"]); - Assert.AreEqual(sendEnt["DateTimeOffsetN"], retrievedEntity["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt["DateTimeOffset"], retrievedEntity["DateTimeOffset"]); - Assert.AreEqual(sendEnt["DateTime"], retrievedEntity["DateTime"]); - Assert.AreEqual(sendEnt["DateTimeN"], retrievedEntity["DateTimeN"]); - } - - [TestMethod] - [Description("A test to check batch retrieve with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveWithResolverSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver); - - // not found - IList results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)results.First().Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - - [TestMethod] - [Description("A test to check batch retrieve with ITableEntity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveWithITableEntitySync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - results = currentTable.ExecuteBatch(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt["foo"], retrievedEntity["foo"]); - } - #endregion - - #region APM - [TestMethod] - [Description("A test to check batch retrieve functionality APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(pk); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt["String"], retrievedEntity["String"]); - Assert.AreEqual(sendEnt["Int64"], retrievedEntity["Int64"]); - Assert.AreEqual(sendEnt["LongPrimitive"], retrievedEntity["LongPrimitive"]); - Assert.AreEqual(sendEnt["Int32"], retrievedEntity["Int32"]); - Assert.AreEqual(sendEnt["IntegerPrimitive"], retrievedEntity["IntegerPrimitive"]); - Assert.AreEqual(sendEnt["Guid"], retrievedEntity["Guid"]); - Assert.AreEqual(sendEnt["Double"], retrievedEntity["Double"]); - Assert.AreEqual(sendEnt["DoublePrimitive"], retrievedEntity["DoublePrimitive"]); - Assert.AreEqual(sendEnt["BinaryPrimitive"], retrievedEntity["BinaryPrimitive"]); - Assert.AreEqual(sendEnt["Binary"], retrievedEntity["Binary"]); - Assert.AreEqual(sendEnt["BoolPrimitive"], retrievedEntity["BoolPrimitive"]); - Assert.AreEqual(sendEnt["Bool"], retrievedEntity["Bool"]); - Assert.AreEqual(sendEnt["DateTimeOffsetN"], retrievedEntity["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt["DateTimeOffset"], retrievedEntity["DateTimeOffset"]); - Assert.AreEqual(sendEnt["DateTime"], retrievedEntity["DateTime"]); - Assert.AreEqual(sendEnt["DateTimeN"], retrievedEntity["DateTimeN"]); - } - - [TestMethod] - [Description("A test to check batch retrieve with resolver APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveWithResolverAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver); - - // not found - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)results.First().Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - - [TestMethod] - [Description("A test to check batch retrieve with ITableEntity APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchRetrieveWithITableEntityAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteBatch(batch, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - results = currentTable.EndExecuteBatch(asyncRes); - } - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - // Validate entity - Assert.AreEqual(sendEnt["foo"], retrievedEntity["foo"]); - } - #endregion - #endregion - - #region Empty Keys Test - - [TestMethod] - [Description("TableBatchOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchOperationsWithEmptyKeys() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity - TableBatchOperation retrieveBatch = new TableBatchOperation(); - retrieveBatch.Retrieve(ent.PartitionKey, ent.RowKey); - TableResult result = currentTable.ExecuteBatch(retrieveBatch).First(); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - currentTable.ExecuteBatch(batch); - - result = currentTable.ExecuteBatch(retrieveBatch).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - currentTable.ExecuteBatch(batch); - - result = currentTable.ExecuteBatch(retrieveBatch).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - result = currentTable.ExecuteBatch(retrieveBatch).First(); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity & Verify Contents - result = currentTable.ExecuteBatch(retrieveBatch).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - batch = new TableBatchOperation(); - batch.Delete(retrievedEntity); - currentTable.ExecuteBatch(batch); - - // Retrieve Entity - result = currentTable.ExecuteBatch(retrieveBatch).First(); - Assert.IsNull(result.Result); - } - - #endregion - - #region Bulk insert - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsert1() - { - InsertAndDeleteBatchWithNEntities(1); - } - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 10")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsert10() - { - InsertAndDeleteBatchWithNEntities(10); - } - - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 99")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsert99() - { - InsertAndDeleteBatchWithNEntities(99); - } - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 100")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsert100() - { - InsertAndDeleteBatchWithNEntities(100); - } - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 100")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertPOCO100() - { - POCOInsertAndDeleteBatchWithNEntities(100); - } - - private void InsertAndDeleteBatchWithNEntities(int n) - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < n; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - IList results = currentTable.ExecuteBatch(batch); - - TableBatchOperation delBatch = new TableBatchOperation(); - - foreach (TableResult res in results) - { - delBatch.Delete((ITableEntity)res.Result); - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.Created); - } - - IList delResults = currentTable.ExecuteBatch(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - - private void POCOInsertAndDeleteBatchWithNEntities(int n) - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < n; m++) - { - batch.Insert(new BaseEntity(pk, Guid.NewGuid().ToString())); - } - - IList results = currentTable.ExecuteBatch(batch); - - TableBatchOperation delBatch = new TableBatchOperation(); - - foreach (TableResult res in results) - { - delBatch.Delete((ITableEntity)res.Result); - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.Created); - } - - IList delResults = currentTable.ExecuteBatch(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Bulk Upsert - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMerge1() - { - InsertOrMergeBatchWithNEntities(1); - } - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 10")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMerge10() - { - InsertOrMergeBatchWithNEntities(10); - } - - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 99")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMerge99() - { - InsertOrMergeBatchWithNEntities(99); - } - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 100")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchInsertOrMerge100() - { - InsertOrMergeBatchWithNEntities(100); - } - - private void InsertOrMergeBatchWithNEntities(int n) - { - string pk = Guid.NewGuid().ToString(); - - TableBatchOperation insertBatch = new TableBatchOperation(); - TableBatchOperation mergeBatch = new TableBatchOperation(); - TableBatchOperation delBatch = new TableBatchOperation(); - - for (int m = 0; m < n; m++) - { - insertBatch.InsertOrMerge(GenerateRandomEnitity(pk)); - } - - IList results = currentTable.ExecuteBatch(insertBatch); - foreach (TableResult res in results) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // update entity and add to merge batch - DynamicTableEntity ent = res.Result as DynamicTableEntity; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - mergeBatch.InsertOrMerge(ent); - - } - - // execute insertOrMerge batch, this time entities exist - IList mergeResults = currentTable.ExecuteBatch(mergeBatch); - - foreach (TableResult res in mergeResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // Add to delete batch - delBatch.Delete((ITableEntity)res.Result); - } - - IList delResults = currentTable.ExecuteBatch(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Boundary Conditions - - [TestMethod] - [Description("Ensure that adding null to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddNullShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - try - { - batch.Add(null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that adding multiple queries to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddMultiQueryShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve("foo", "bar"); - try - { - batch.Retrieve("foo", "bar2"); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that a batch that contains multiple operations on the same entity fails")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchWithMultipleOperationsOnSameEntityShouldFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - // Add entity 0 - ITableEntity first = GenerateRandomEnitity(pk); - batch.Insert(first); - - // Add entities 1 - 98 - for (int m = 1; m < 99; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - // Insert Duplicate of entity 0 - batch.Insert(first); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, new string[] { "99:One of the request inputs is not valid." }, false); - } - } - - [TestMethod] - [Description("Ensure that a batch with over 100 entities will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchOver100EntitiesShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < 101; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - [TestMethod] - [Description("Ensure that a batch with entity over 1 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchEntityOver1MBShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity ent = GenerateRandomEnitity(pk); - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - - [TestMethod] - [Description("Ensure that a batch over 4 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchOver4MBShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 65; m++) - { - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - // Maximum Entity size is 64KB - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[64 * 1024])); - batch.Insert(ent); - } - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "ContentLengthExceeded" }, "The content length for the requested operation has exceeded the limit (4MB)."); - } - } - - [TestMethod] - [Description("Ensure that a query and one more operation will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddQueryAndOneMoreOperationShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - TableOperation operation = TableOperation.Retrieve("foo", "bar"); - - try - { - batch.Add(operation); - Assert.IsTrue(batch.Contains(operation)); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - Assert.IsFalse(batch.Contains(operation)); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Add(TableOperation.Retrieve("foo", "bar")); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - - try - { - batch.Add(TableOperation.Retrieve("foo", "bar")); - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Insert(0, TableOperation.Retrieve("foo", "bar")); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - } - - [TestMethod] - [Description("Ensure that empty batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchEmptyBatchShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - TestHelper.ExpectedException( - () => currentTable.ExecuteBatch(batch), - "Empty batch operation should fail"); - } - - [TestMethod] - [Description("Ensure that a given batch only allows entities with the same partitionkey")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchLockToPartitionKey() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - // should reset pk lock - batch.RemoveAt(0); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - } - catch (ArgumentException) - { - Assert.Fail(); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that a batch with an entity property over 255 chars will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchWithPropertyOver255CharsShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - string propName = new string('a', 256); - - DynamicTableEntity ent = new DynamicTableEntity("foo", "bar"); - ent.Properties.Add(propName, new EntityProperty("propbar")); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteBatch(batch, null, opContext); - Assert.Fail(); - } - - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "PropertyNameTooLong" }, "The property name exceeds the maximum allowed length (255)."); - } - } - - [TestMethod] - [Description("Test a Table batch operation that retried has the correct number of results returned to the user")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchOperationWithRetryHasCorrectNumberOfResults() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableBatchOperation batch = new TableBatchOperation(); - for (int i = 0; i < 100; i++) - { - DynamicTableEntity insertEntity = new DynamicTableEntity("retry test", i.ToString()); - insertEntity.Properties.Add("prop", new EntityProperty(new byte[20 * 1024])); - batch.Insert(insertEntity); - } - - IList results = null; - TestHelper.ExecuteMethodWithRetry( - 3, - new[] { - // Insert upstream network delay to prevent upload to server @ 1000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 500 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (options, opContext) => results = currentTable.ExecuteBatch(batch, (TableRequestOptions)options, opContext)); - - Assert.AreEqual(batch.Count, results.Count); - } - - #endregion - - #region Helpers - - private static void AddInsertToBatch(string pk, TableBatchOperation batch) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - private static DynamicTableEntity GenerateRandomEnitity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableEscapingTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableEscapingTests.cs deleted file mode 100644 index b7bf28784671a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableEscapingTests.cs +++ /dev/null @@ -1,409 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableEscapingTests : TableTestBase - { - #region Locals + Ctors - public TableEscapingTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - [TestMethod] - [Description("Escaping test for whitespace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingWhiteSpaceOnly() - { - this.DoEscapeTest(" ", false, true); - } - - [TestMethod] - [Description("Escaping test for whitespace in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingWhiteSpaceOnlyInBatch() - { - this.DoEscapeTest(" ", true, true); - } - - [TestMethod] - [Description("Escaping test for leading and trailing whitespace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingWhiteSpaceLeadingTrailing() - { - this.DoEscapeTest(" foo ", false, true); - } - - [TestMethod] - [Description("Escaping test for leading and trailing whitespace in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingWhiteSpaceLeadingTrailingInBatch() - { - this.DoEscapeTest(" foo ", true, true); - } - - [TestMethod] - [Description("Escaping test for EmptyString")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingEmptyString() - { - this.DoEscapeTest("", false, true); - } - - [TestMethod] - [Description("Escaping test for EmptyString in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingEmptyStringOnlyInBatch() - { - this.DoEscapeTest("", true, true); - } - - [TestMethod] - [Description("Escaping test for RandomChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingRandomChars() - { - this.DoEscapeTest("!$'\"()*+,;=", false, false); - } - - [TestMethod] - [Description("Escaping test for RandomChars in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingRandomCharsInBatch() - { - this.DoEscapeTest("!$'\"()*+,;=", true, false); - } - - [TestMethod] - [Description("Escaping test for Percent25")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingPercent25() - { - this.DoEscapeTest("foo%25", false, true); - } - - [TestMethod] - [Description("Escaping test for Percent25 in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingPercent25InBatch() - { - this.DoEscapeTest("foo%25", true, true); - } - - [TestMethod] - [Description("Escaping test for SpecialChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEscapingSpecialChars() - { - this.DoEscapeTest("\\ // @ ? ", false, false); - this.DoEscapeTest("", false, false); - this.DoEscapeTest("", false, false); - this.DoEscapeTest("!<", false, false); - this.DoEscapeTest("", true, false); - this.DoEscapeTest("", true, false); - this.DoEscapeTest("", true, false); - this.DoEscapeTest("!<", true, false); - this.DoEscapeTest(" -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableOperationUnitTests : TableTestBase - { - #region Locals + Ctors - public TableOperationUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - TableEntity.DisableCompiledSerializers = false; - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExists(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Insert - - #region Sync - [TestMethod] - [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableOperation operation = TableOperation.Retrieve(ent.PartitionKey, ent.RowKey); - Assert.IsFalse(operation.IsTableEntity); - TableResult result = currentTable.Execute(operation); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - } - - [TestMethod] - [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertSingleQuoteSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "partition'key", RowKey = "row'key" }; - ent.Properties.Add("stringprop", new EntityProperty("string'value")); - currentTable.Execute(TableOperation.InsertOrReplace(ent)); - - TableQuery query = new TableQuery().Where(TableQuery.CombineFilters( - (TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ent.PartitionKey)), - TableOperators.And, - (TableQuery.GenerateFilterCondition("stringprop", QueryComparisons.Equal, ent.Properties["stringprop"].StringValue)))); - - foreach (DynamicTableEntity retrievedEntity in currentTable.ExecuteQuery(query)) - { - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties["stringprop"].StringValue, retrievedEntity.Properties["stringprop"].StringValue); - } - - // Check the iqueryable way. - IEnumerable result = (from entity in currentTable.CreateQuery() - where entity.PartitionKey == ent.PartitionKey && entity.Properties["stringprop"].StringValue == ent.Properties["stringprop"].StringValue - select entity); - - foreach (DynamicTableEntity retrievedEntity in result.ToList()) - { - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties["stringprop"].StringValue, retrievedEntity.Properties["stringprop"].StringValue); - } - - ComplexEntity tableEntity = new ComplexEntity() { PartitionKey = "partition'key", RowKey = "row'key" }; - currentTable.Execute(TableOperation.InsertOrReplace(tableEntity)); - - TableQuery query2 = new TableQuery().Where(TableQuery.CombineFilters( - (TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ent.PartitionKey)), - TableOperators.And, - (TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, ent.RowKey)))); - - foreach (ComplexEntity retrievedComplexEntity in currentTable.ExecuteQuery(query2)) - { - Assert.IsNotNull(retrievedComplexEntity); - Assert.AreEqual(ent.PartitionKey, retrievedComplexEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedComplexEntity.RowKey); - } - } - - [TestMethod] - [Description("TableOperation Insert Conflict")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertConflictSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.Execute(TableOperation.Insert(ent)); - - OperationContext opContext = new OperationContext(); - - // Attempt Insert Conflict Entity - DynamicTableEntity conflictEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - try - { - currentTable.Execute(TableOperation.Insert(conflictEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - - [TestMethod] - [Description("Validate maximum table execution time")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore)] - [TestCategory(TenantTypeCategory.DevFabric)] - [TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableMaximumExecutionTime() - { - CloudTableClient client = GenerateCloudTableClient(); - CloudTable table = client.GetTableReference("TestTable"); - table.CreateIfNotExists(); - - TestHelper.ExpectedException( - () => - { client.MaximumExecutionTime = TimeSpan.Zero; }, - "The argument is smaller than the minimum"); - - TestHelper.ExpectedException( - () => - { client.MaximumExecutionTime = TimeSpan.FromSeconds((double)int.MaxValue + 1); }, - "The argument is larger than the maximum"); - - client.MaximumExecutionTime = null; - Assert.IsTrue(client.MaximumExecutionTime.Equals(null)); - - client.MaximumExecutionTime = TimeSpan.FromSeconds(1); - Assert.IsTrue(client.MaximumExecutionTime.Equals(TimeSpan.FromSeconds(1))); - - // Try an operation taking longer than 1 second - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 40; m++) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - - // Maximum Property size is 64KB - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[64 * 1024])); - batch.Insert(ent); - } - - StorageException except = TestHelper.ExpectedException( - () => table.ExecuteBatch(batch), "Operation should take longer than MaximumExecutionTime"); - Assert.IsInstanceOfType(except.InnerException, typeof(TimeoutException)); - } - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Insert APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Insert(ent), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - } - - [TestMethod] - [Description("TableOperation Insert Conflict APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertConflictAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.Execute(TableOperation.Insert(ent)); - - OperationContext opContext = new OperationContext(); - - // Attempt Insert Conflict Entity - DynamicTableEntity conflictEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Insert(conflictEntity), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - - #region Task - [TestMethod] - [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertTask() - { - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.ExecuteAsync(TableOperation.Insert(ent)).Wait(); - - // Retrieve Entity - TableResult result = currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)).Result; - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - } - - [TestMethod] - [Description("TableOperation Insert Conflict")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertConflictTask() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.ExecuteAsync(TableOperation.Insert(ent)).Wait(); - - OperationContext opContext = new OperationContext(); - - // Attempt Insert Conflict Entity - DynamicTableEntity conflictEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - try - { - currentTable.ExecuteAsync(TableOperation.Insert(conflictEntity), null, opContext).Wait(); - Assert.Fail(); - } - catch (AggregateException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - #endregion - - #region Insert Or Merge - - #region Sync - [TestMethod] - [Description("TableOperation Insert Or Merge Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertOrMergeSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.InsertOrMerge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Insert Or Merge APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertOrMergeAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.InsertOrMerge(insertOrMergeEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.InsertOrMerge(mergeEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - #endregion - #endregion - - #region Insert Or Replace - - #region Sync - [TestMethod] - [Description("TableOperation Insert Or ReplaceSync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertOrReplaceSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.InsertOrReplace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Insert Or Replace APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertOrReplaceAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.InsertOrReplace(insertOrReplaceEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.InsertOrReplace(replaceEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - #endregion - - #region Delete - - #region Sync - [TestMethod] - [Description("TableOperation Delete")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationDeleteSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNotNull(result.Result); - - // Delete Entity - currentTable.Execute(TableOperation.Delete(ent)); - - // Retrieve Entity - TableResult result2 = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - [TestMethod] - [Description("TableOperation Delete Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationDeleteFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - OperationContext opContext = new OperationContext(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.ETag = "*"; - - try - { - currentTable.Execute(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - retrievedEntity.Properties["foo"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(retrievedEntity)); - - try - { - opContext = new OperationContext(); - // Now delete old reference with stale etag and validate exception - currentTable.Execute(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Delete APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationDeleteAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNotNull(result.Result); - - // Delete Entity - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Delete(ent), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity - TableResult result2 = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - [TestMethod] - [Description("TableOperation Delete Fail APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationDeleteFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - OperationContext opContext = new OperationContext(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.ETag = "*"; - - try - { - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Delete(ent), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - - - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - retrievedEntity.Properties["foo"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(retrievedEntity)); - - try - { - opContext = new OperationContext(); - // Now delete old reference with stale etag and validate exception - currentTable.Execute(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - - #endregion - #endregion - - #region Merge - - #region Sync - [TestMethod] - [Description("TableOperation Merge Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationMergeSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Merge Fail Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationMergeFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Merge APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationMergeAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Merge(mergeEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Merge Fail APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationMergeFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Merge(mergeEntity), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Merge(mergeEntity), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - #endregion - - #region Replace - - #region Sync - [TestMethod] - [Description("TableOperation Replace Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationReplaceSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Replace Fail Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationReplaceFailSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - currentTable.Execute(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region APM - [TestMethod] - [Description("TableOperation Replace APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationReplaceAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Replace(replaceEntity), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - // Retrieve Entity & Verify Contents - TableResult result = currentTable.Execute(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Replace Fail APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationReplaceFailAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - currentTable.Execute(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - currentTable.Execute(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Replace(replaceEntity), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - currentTable.Execute(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Replace(replaceEntity), null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - currentTable.EndExecute(asyncRes); - } - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #endregion - - #region Retrieve - - #region Sync - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEdmTypeCheck() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - ComplexEntity ent = new ComplexEntity(); - - ent.String = null; - sendEnt.Properties = ent.WriteEntity(null); - - string value = sendEnt.Properties["String"].StringValue; - Assert.AreEqual(EdmType.String, sendEnt.Properties["String"].PropertyType); - - sendEnt.Properties["String"].StringValue = "helloworld"; - Assert.AreEqual(EdmType.String, sendEnt.Properties["String"].PropertyType); - - sendEnt.Properties["String"].StringValue = null; - Assert.AreEqual(EdmType.String, sendEnt.Properties["String"].PropertyType); - - ent.Binary = null; - sendEnt.Properties = ent.WriteEntity(null); - - byte[] binaryValue = sendEnt.Properties["Binary"].BinaryValue; - Assert.AreEqual(EdmType.Binary, sendEnt.Properties["Binary"].PropertyType); - - sendEnt.Properties["Binary"].BinaryValue = new byte[] { 1, 2 }; - Assert.AreEqual(EdmType.Binary, sendEnt.Properties["Binary"].PropertyType); - - sendEnt.Properties["Binary"].BinaryValue = null; - Assert.AreEqual(EdmType.Binary, sendEnt.Properties["Binary"].PropertyType); - - ent.DateTimeN = null; - sendEnt.Properties = ent.WriteEntity(null); - - DateTime? dateTimeValue = sendEnt.Properties["DateTimeN"].DateTime; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeN"].PropertyType); - - sendEnt.Properties["DateTimeN"].DateTime = DateTime.Now; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeN"].PropertyType); - - sendEnt.Properties["DateTimeN"].DateTime = null; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeN"].PropertyType); - - ent.DateTimeOffsetN = null; - sendEnt.Properties = ent.WriteEntity(null); - - DateTimeOffset? dateTimeOffsetValue = sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeOffsetN"].PropertyType); - - sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue = DateTimeOffset.Now; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeOffsetN"].PropertyType); - - sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue = null; - Assert.AreEqual(EdmType.DateTime, sendEnt.Properties["DateTimeOffsetN"].PropertyType); - - ent.DoubleN = null; - sendEnt.Properties = ent.WriteEntity(null); - - double? doubleValue = sendEnt.Properties["DoubleN"].DoubleValue; - Assert.AreEqual(EdmType.Double, sendEnt.Properties["DoubleN"].PropertyType); - - sendEnt.Properties["DoubleN"].DoubleValue = 1234.5678; - Assert.AreEqual(EdmType.Double, sendEnt.Properties["DoubleN"].PropertyType); - - sendEnt.Properties["DoubleN"].DoubleValue = null; - Assert.AreEqual(EdmType.Double, sendEnt.Properties["DoubleN"].PropertyType); - - ent.GuidN = null; - sendEnt.Properties = ent.WriteEntity(null); - - Guid? guidValue = sendEnt.Properties["GuidN"].GuidValue; - Assert.AreEqual(EdmType.Guid, sendEnt.Properties["GuidN"].PropertyType); - - sendEnt.Properties["GuidN"].GuidValue = Guid.NewGuid(); - Assert.AreEqual(EdmType.Guid, sendEnt.Properties["GuidN"].PropertyType); - - sendEnt.Properties["GuidN"].GuidValue = null; - Assert.AreEqual(EdmType.Guid, sendEnt.Properties["GuidN"].PropertyType); - - ent.Int32N = null; - sendEnt.Properties = ent.WriteEntity(null); - - int? intValue = sendEnt.Properties["Int32N"].Int32Value; - Assert.AreEqual(EdmType.Int32, sendEnt.Properties["Int32N"].PropertyType); - - sendEnt.Properties["Int32N"].Int32Value = 123; - Assert.AreEqual(EdmType.Int32, sendEnt.Properties["Int32N"].PropertyType); - - sendEnt.Properties["Int32N"].Int32Value = null; - Assert.AreEqual(EdmType.Int32, sendEnt.Properties["Int32N"].PropertyType); - - ent.LongPrimitiveN = null; - sendEnt.Properties = ent.WriteEntity(null); - - long? longValue = sendEnt.Properties["LongPrimitiveN"].Int64Value; - Assert.AreEqual(EdmType.Int64, sendEnt.Properties["LongPrimitiveN"].PropertyType); - - sendEnt.Properties["LongPrimitiveN"].Int64Value = 1234; - Assert.AreEqual(EdmType.Int64, sendEnt.Properties["LongPrimitiveN"].PropertyType); - - sendEnt.Properties["LongPrimitiveN"].Int64Value = null; - Assert.AreEqual(EdmType.Int64, sendEnt.Properties["LongPrimitiveN"].PropertyType); - - ent.BoolN = null; - sendEnt.Properties = ent.WriteEntity(null); - - bool? booleanValue = sendEnt.Properties["BoolN"].BooleanValue; - Assert.AreEqual(EdmType.Boolean, sendEnt.Properties["BoolN"].PropertyType); - - sendEnt.Properties["BoolN"].BooleanValue = true; - Assert.AreEqual(EdmType.Boolean, sendEnt.Properties["BoolN"].PropertyType); - - sendEnt.Properties["BoolN"].BooleanValue = null; - Assert.AreEqual(EdmType.Boolean, sendEnt.Properties["BoolN"].PropertyType); - } - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - // not found - TableResult result = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - result = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt["String"], retrievedEntity["String"]); - - Assert.AreEqual(sendEnt["Int64"], retrievedEntity["Int64"]); - Assert.AreEqual(sendEnt["Int64N"], retrievedEntity["Int64N"]); - - Assert.AreEqual(sendEnt["LongPrimitive"], retrievedEntity["LongPrimitive"]); - Assert.AreEqual(sendEnt["LongPrimitiveN"], retrievedEntity["LongPrimitiveN"]); - - Assert.AreEqual(sendEnt["Int32"], retrievedEntity["Int32"]); - Assert.AreEqual(sendEnt["Int32N"], retrievedEntity["Int32N"]); - Assert.AreEqual(sendEnt["IntegerPrimitive"], retrievedEntity["IntegerPrimitive"]); - Assert.AreEqual(sendEnt["IntegerPrimitiveN"], retrievedEntity["IntegerPrimitiveN"]); - - Assert.AreEqual(sendEnt["Guid"], retrievedEntity["Guid"]); - Assert.AreEqual(sendEnt["GuidN"], retrievedEntity["GuidN"]); - - Assert.AreEqual(sendEnt["Double"], retrievedEntity["Double"]); - Assert.AreEqual(sendEnt["DoubleN"], retrievedEntity["DoubleN"]); - Assert.AreEqual(sendEnt["DoublePrimitive"], retrievedEntity["DoublePrimitive"]); - Assert.AreEqual(sendEnt["DoublePrimitiveN"], retrievedEntity["DoublePrimitiveN"]); - - Assert.AreEqual(sendEnt["BinaryPrimitive"], retrievedEntity["BinaryPrimitive"]); - Assert.AreEqual(sendEnt["Binary"], retrievedEntity["Binary"]); - - Assert.AreEqual(sendEnt["BoolPrimitive"], retrievedEntity["BoolPrimitive"]); - Assert.AreEqual(sendEnt["BoolPrimitiveN"], retrievedEntity["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt["Bool"], retrievedEntity["Bool"]); - Assert.AreEqual(sendEnt["BoolN"], retrievedEntity["BoolN"]); - - Assert.AreEqual(sendEnt["DateTimeOffset"], retrievedEntity["DateTimeOffset"]); - Assert.AreEqual(sendEnt["DateTimeOffsetN"], retrievedEntity["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt["DateTime"], retrievedEntity["DateTime"]); - Assert.AreEqual(sendEnt["DateTimeN"], retrievedEntity["DateTimeN"]); - } - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveSyncWithReflection() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - ComplexEntity sendEnt = new ComplexEntity(pk, rk); - sendEnt.Binary = new Byte[] { 5, 6, 7, 8 }; - sendEnt.BinaryNull = null; - sendEnt.BinaryPrimitive = new byte[] { 5, 6, 7, 8 }; - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = null; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = null; - sendEnt.Double = (Double)5678.5678; - sendEnt.DoubleN = (Double)5678.5678; - sendEnt.DoubleNull = null; - sendEnt.DoublePrimitive = (double)5678.5678; - sendEnt.DoublePrimitiveN = (double)5678.5678; - sendEnt.DoublePrimitiveNull = null; - sendEnt.Guid = Guid.NewGuid(); - sendEnt.GuidN = Guid.NewGuid(); - sendEnt.GuidNull = null; - sendEnt.Int32 = 5678; - sendEnt.Int32N = 5678; - sendEnt.Int32Null = null; - sendEnt.Int64 = (long)5678; - sendEnt.Int64N = (long)5678; - sendEnt.Int64Null = null; - sendEnt.IntegerPrimitive = 5678; - sendEnt.IntegerPrimitiveN = 5678; - sendEnt.IntegerPrimitiveNull = null; - sendEnt.LongPrimitive = 5678; - sendEnt.LongPrimitiveN = 5678; - sendEnt.LongPrimitiveNull = null; - sendEnt.String = "ResetTestTotested"; - currentTable.Execute(TableOperation.Insert(sendEnt)); - - TableResult res = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - ComplexEntity retrievedEntity = res.Result as ComplexEntity; - - Assert.AreEqual(sendEnt.String, retrievedEntity.String); - - Assert.AreEqual(sendEnt.Int64, retrievedEntity.Int64); - Assert.AreEqual(sendEnt.Int64N, retrievedEntity.Int64N); - Assert.AreEqual(sendEnt.Int64Null, retrievedEntity.Int64Null); - - Assert.AreEqual(sendEnt.LongPrimitive, retrievedEntity.LongPrimitive); - Assert.AreEqual(sendEnt.LongPrimitiveN, retrievedEntity.LongPrimitiveN); - Assert.AreEqual(sendEnt.LongPrimitiveNull, retrievedEntity.LongPrimitiveNull); - - Assert.AreEqual(sendEnt.Int32, retrievedEntity.Int32); - Assert.AreEqual(sendEnt.Int32N, retrievedEntity.Int32N); - Assert.AreEqual(sendEnt.Int32Null, retrievedEntity.Int32Null); - Assert.AreEqual(sendEnt.IntegerPrimitive, retrievedEntity.IntegerPrimitive); - Assert.AreEqual(sendEnt.IntegerPrimitiveN, retrievedEntity.IntegerPrimitiveN); - Assert.AreEqual(sendEnt.IntegerPrimitiveNull, retrievedEntity.IntegerPrimitiveNull); - - Assert.AreEqual(sendEnt.Guid, retrievedEntity.Guid); - Assert.AreEqual(sendEnt.GuidN, retrievedEntity.GuidN); - Assert.AreEqual(sendEnt.GuidNull, retrievedEntity.GuidNull); - - Assert.AreEqual(sendEnt.Double, retrievedEntity.Double); - Assert.AreEqual(sendEnt.DoubleN, retrievedEntity.DoubleN); - Assert.AreEqual(sendEnt.DoubleNull, retrievedEntity.DoubleNull); - Assert.AreEqual(sendEnt.DoublePrimitive, retrievedEntity.DoublePrimitive); - Assert.AreEqual(sendEnt.DoublePrimitiveN, retrievedEntity.DoublePrimitiveN); - Assert.AreEqual(sendEnt.DoublePrimitiveNull, retrievedEntity.DoublePrimitiveNull); - - Assert.AreEqual(sendEnt.BinaryPrimitive.GetValue(0), retrievedEntity.BinaryPrimitive.GetValue(0)); - Assert.AreEqual(sendEnt.BinaryPrimitive.GetValue(1), retrievedEntity.BinaryPrimitive.GetValue(1)); - Assert.AreEqual(sendEnt.BinaryPrimitive.GetValue(2), retrievedEntity.BinaryPrimitive.GetValue(2)); - Assert.AreEqual(sendEnt.BinaryPrimitive.GetValue(3), retrievedEntity.BinaryPrimitive.GetValue(3)); - - Assert.AreEqual(sendEnt.BinaryNull, retrievedEntity.BinaryNull); - Assert.AreEqual(sendEnt.Binary.GetValue(0), retrievedEntity.Binary.GetValue(0)); - Assert.AreEqual(sendEnt.Binary.GetValue(1), retrievedEntity.Binary.GetValue(1)); - Assert.AreEqual(sendEnt.Binary.GetValue(2), retrievedEntity.Binary.GetValue(2)); - Assert.AreEqual(sendEnt.Binary.GetValue(3), retrievedEntity.Binary.GetValue(3)); - - - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.BoolPrimitiveN); - Assert.AreEqual(sendEnt.BoolPrimitiveNull, retrievedEntity.BoolPrimitiveNull); - Assert.AreEqual(sendEnt.Bool, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.BoolNull, retrievedEntity.BoolNull); - - Assert.AreEqual(sendEnt.DateTimeOffset, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.DateTimeOffsetN); - Assert.AreEqual(sendEnt.DateTimeOffsetNull, retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.DateTimeNull, retrievedEntity.DateTimeNull); - } - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveEntityPropertySetter() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - ComplexEntity sendEnt = new ComplexEntity(); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - Dictionary properties = new Dictionary(); - - EntityProperty prop1 = properties["BoolN"] = EntityProperty.GeneratePropertyForBool(null); - sendEnt.BoolN = prop1.BooleanValue = true; - - EntityProperty prop2 = properties["DoubleN"] = EntityProperty.GeneratePropertyForDouble(null); - sendEnt.DoubleN = prop2.DoubleValue = 3.1415; - - EntityProperty prop3 = properties["GuidN"] = EntityProperty.GeneratePropertyForGuid(null); - sendEnt.GuidN = prop3.GuidValue = Guid.NewGuid(); - - EntityProperty prop4 = properties["Int32N"] = EntityProperty.GeneratePropertyForInt(null); - sendEnt.Int32N = prop4.Int32Value = 1; - - EntityProperty prop5 = properties["Int64N"] = EntityProperty.GeneratePropertyForLong(null); - sendEnt.Int64N = prop5.Int64Value = 1234; - - EntityProperty prop6 = properties["String"] = EntityProperty.GeneratePropertyForString(null); - sendEnt.String = prop6.StringValue = "hello"; - - EntityProperty prop7 = properties["DateTimeOffsetN"] = EntityProperty.GeneratePropertyForDateTimeOffset(null); - sendEnt.DateTimeOffsetN = prop7.DateTimeOffsetValue = DateTimeOffset.UtcNow; - - ComplexEntity retrievedEntity = new ComplexEntity(); - retrievedEntity.ReadEntity(properties, null); - - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.DoubleN, retrievedEntity.DoubleN); - Assert.AreEqual(sendEnt.GuidN, retrievedEntity.GuidN); - Assert.AreEqual(sendEnt.Int32N, retrievedEntity.Int32N); - Assert.AreEqual(sendEnt.Int64N, retrievedEntity.Int64N); - Assert.AreEqual(sendEnt.String, retrievedEntity.String); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.DateTimeOffsetN); - } - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveWithResolverSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.PartitionKey = Guid.NewGuid().ToString(); - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - // not found - TableResult result = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - result = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)result.Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - - [TestMethod] - [Description("A test to check ignore property attribute while serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveWithIgnoreAttributeWrite() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - IgnoreEntity sendEnt = new IgnoreEntity(pk, rk); - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = true; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = DateTimeOffset.Now.AddMinutes(1); - - currentTable.Execute(TableOperation.Insert(sendEnt)); - - TableResult result = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("BoolPrimitiveNull")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("Bool")); - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.Properties["BoolPrimitive"].BooleanValue); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.Properties["BoolPrimitiveN"].BooleanValue); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.Properties["BoolN"].BooleanValue); - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffset")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffsetNull")); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.Properties["DateTimeOffsetN"].DateTimeOffsetValue); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.Properties["DateTime"].DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.Properties["DateTimeN"].DateTime); - } - - [TestMethod] - [Description("A test to check ignore property attribute while de-serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveWithIgnoreAttributeRead() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.Properties.Add("Bool", new EntityProperty(true)); - sendEnt.Properties.Add("BoolN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolNull", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitive", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveNull", new EntityProperty(true)); - sendEnt.Properties.Add("DateTime", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeN", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeNull", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffset", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetN", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetNull", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, pk)); - IEnumerable result = currentTable.ExecuteQuery(query); - IgnoreEntity retrievedEntity = result.ToList().First() as IgnoreEntity; - - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"].BooleanValue, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"].BooleanValue, retrievedEntity.BoolPrimitiveN); - Assert.AreNotEqual(sendEnt.Properties["BoolPrimitiveNull"].BooleanValue, retrievedEntity.BoolPrimitiveNull); - Assert.AreNotEqual(sendEnt.Properties["Bool"].BooleanValue, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.Properties["BoolN"].BooleanValue, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.Properties["BoolNull"].BooleanValue, retrievedEntity.BoolNull); - - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffset"].DateTimeOffsetValue, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetN); - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffsetNull"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetNull); - Assert.IsNull(retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.Properties["DateTime"].DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.Properties["DateTimeN"].DateTime, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.Properties["DateTimeNull"].DateTime, retrievedEntity.DateTimeNull); - } - - [TestMethod] - [Description("A test to check compiled and reflection serializers (WriteEntity)")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEntityCompiledVSReflectionSerializationEqualityTest() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - ComplexEntity sendEnt = new ComplexEntity(pk, rk); - sendEnt.Binary = new Byte[] { 5, 6, 7, 8 }; - sendEnt.BinaryNull = null; - sendEnt.BinaryPrimitive = new byte[] { 5, 6, 7, 8 }; - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = null; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = null; - sendEnt.Double = (Double)5678.5678; - sendEnt.DoubleN = (Double)5678.5678; - sendEnt.DoubleNull = null; - sendEnt.DoublePrimitive = (double)5678.5678; - sendEnt.DoublePrimitiveN = (double)5678.5678; - sendEnt.DoublePrimitiveNull = null; - sendEnt.Guid = Guid.NewGuid(); - sendEnt.GuidN = Guid.NewGuid(); - sendEnt.GuidNull = null; - sendEnt.Int32 = 5678; - sendEnt.Int32N = 5678; - sendEnt.Int32Null = null; - sendEnt.Int64 = (long)5678; - sendEnt.Int64N = (long)5678; - sendEnt.Int64Null = null; - sendEnt.IntegerPrimitive = 5678; - sendEnt.IntegerPrimitiveN = 5678; - sendEnt.IntegerPrimitiveNull = null; - sendEnt.LongPrimitive = 5678; - sendEnt.LongPrimitiveN = 5678; - sendEnt.LongPrimitiveNull = null; - sendEnt.String = "ResetTestTotested"; - - TableEntity.DisableCompiledSerializers = true; - var reflectionDict = sendEnt.WriteEntity(null); - Assert.IsNull(sendEnt.CompiledWrite); - - TableEntity.DisableCompiledSerializers = false; - var compiledDict = sendEnt.WriteEntity(null); - Assert.IsNotNull(sendEnt.CompiledWrite); - - // Assert Serialized Dictionaries are the same - Assert.AreEqual(reflectionDict.Count, compiledDict.Count); - foreach (var kvp in reflectionDict) - { - Assert.IsTrue(compiledDict.ContainsKey(kvp.Key)); - Assert.AreEqual(reflectionDict[kvp.Key], compiledDict[kvp.Key]); - } - } - - [TestMethod] - [Description("A test to validate the Compiled and Reflection deserializers (ReadEntity)")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEntityCompiledVSReflectionDeSerializationEqualityTest() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - TableEntity.DisableCompiledSerializers = true; - ComplexEntity sendEnt = new ComplexEntity(pk, rk); - sendEnt.Binary = new Byte[] { 5, 6, 7, 8 }; - sendEnt.BinaryNull = null; - sendEnt.BinaryPrimitive = new byte[] { 5, 6, 7, 8 }; - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = null; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = null; - sendEnt.Double = (Double)5678.5678; - sendEnt.DoubleN = (Double)5678.5678; - sendEnt.DoubleNull = null; - sendEnt.DoublePrimitive = (double)5678.5678; - sendEnt.DoublePrimitiveN = (double)5678.5678; - sendEnt.DoublePrimitiveNull = null; - sendEnt.Guid = Guid.NewGuid(); - sendEnt.GuidN = Guid.NewGuid(); - sendEnt.GuidNull = null; - sendEnt.Int32 = 5678; - sendEnt.Int32N = 5678; - sendEnt.Int32Null = null; - sendEnt.Int64 = (long)5678; - sendEnt.Int64N = (long)5678; - sendEnt.Int64Null = null; - sendEnt.IntegerPrimitive = 5678; - sendEnt.IntegerPrimitiveN = 5678; - sendEnt.IntegerPrimitiveNull = null; - sendEnt.LongPrimitive = 5678; - sendEnt.LongPrimitiveN = 5678; - sendEnt.LongPrimitiveNull = null; - sendEnt.String = "ResetTestTotested"; - currentTable.Execute(TableOperation.Insert(sendEnt)); - - TableEntity.DisableCompiledSerializers = true; - TableResult res = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - ComplexEntity reflectionEntity = res.Result as ComplexEntity; - Assert.IsNull(reflectionEntity.CompiledRead); - - TableEntity.DisableCompiledSerializers = false; - TableResult res2 = currentTable.Execute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - ComplexEntity compiledEntity = res2.Result as ComplexEntity; - Assert.IsNotNull(compiledEntity.CompiledRead); - - // Assert Deserialized Entities are the same - Assert.AreEqual(compiledEntity.String, reflectionEntity.String); - - Assert.AreEqual(compiledEntity.Int64, reflectionEntity.Int64); - Assert.AreEqual(compiledEntity.Int64N, reflectionEntity.Int64N); - Assert.AreEqual(compiledEntity.Int64Null, reflectionEntity.Int64Null); - - Assert.AreEqual(compiledEntity.LongPrimitive, reflectionEntity.LongPrimitive); - Assert.AreEqual(compiledEntity.LongPrimitiveN, reflectionEntity.LongPrimitiveN); - Assert.AreEqual(compiledEntity.LongPrimitiveNull, reflectionEntity.LongPrimitiveNull); - - Assert.AreEqual(compiledEntity.Int32, reflectionEntity.Int32); - Assert.AreEqual(compiledEntity.Int32N, reflectionEntity.Int32N); - Assert.AreEqual(compiledEntity.Int32Null, reflectionEntity.Int32Null); - Assert.AreEqual(compiledEntity.IntegerPrimitive, reflectionEntity.IntegerPrimitive); - Assert.AreEqual(compiledEntity.IntegerPrimitiveN, reflectionEntity.IntegerPrimitiveN); - Assert.AreEqual(compiledEntity.IntegerPrimitiveNull, reflectionEntity.IntegerPrimitiveNull); - - Assert.AreEqual(compiledEntity.Guid, reflectionEntity.Guid); - Assert.AreEqual(compiledEntity.GuidN, reflectionEntity.GuidN); - Assert.AreEqual(compiledEntity.GuidNull, reflectionEntity.GuidNull); - - Assert.AreEqual(compiledEntity.Double, reflectionEntity.Double); - Assert.AreEqual(compiledEntity.DoubleN, reflectionEntity.DoubleN); - Assert.AreEqual(compiledEntity.DoubleNull, reflectionEntity.DoubleNull); - Assert.AreEqual(compiledEntity.DoublePrimitive, reflectionEntity.DoublePrimitive); - Assert.AreEqual(compiledEntity.DoublePrimitiveN, reflectionEntity.DoublePrimitiveN); - Assert.AreEqual(compiledEntity.DoublePrimitiveNull, reflectionEntity.DoublePrimitiveNull); - - Assert.AreEqual(compiledEntity.BinaryPrimitive.GetValue(0), reflectionEntity.BinaryPrimitive.GetValue(0)); - Assert.AreEqual(compiledEntity.BinaryPrimitive.GetValue(1), reflectionEntity.BinaryPrimitive.GetValue(1)); - Assert.AreEqual(compiledEntity.BinaryPrimitive.GetValue(2), reflectionEntity.BinaryPrimitive.GetValue(2)); - Assert.AreEqual(compiledEntity.BinaryPrimitive.GetValue(3), reflectionEntity.BinaryPrimitive.GetValue(3)); - - Assert.AreEqual(compiledEntity.BinaryNull, reflectionEntity.BinaryNull); - Assert.AreEqual(compiledEntity.Binary.GetValue(0), reflectionEntity.Binary.GetValue(0)); - Assert.AreEqual(compiledEntity.Binary.GetValue(1), reflectionEntity.Binary.GetValue(1)); - Assert.AreEqual(compiledEntity.Binary.GetValue(2), reflectionEntity.Binary.GetValue(2)); - Assert.AreEqual(compiledEntity.Binary.GetValue(3), reflectionEntity.Binary.GetValue(3)); - - Assert.AreEqual(compiledEntity.BoolPrimitive, reflectionEntity.BoolPrimitive); - Assert.AreEqual(compiledEntity.BoolPrimitiveN, reflectionEntity.BoolPrimitiveN); - Assert.AreEqual(compiledEntity.BoolPrimitiveNull, reflectionEntity.BoolPrimitiveNull); - Assert.AreEqual(compiledEntity.Bool, reflectionEntity.Bool); - Assert.AreEqual(compiledEntity.BoolN, reflectionEntity.BoolN); - Assert.AreEqual(compiledEntity.BoolNull, reflectionEntity.BoolNull); - - Assert.AreEqual(compiledEntity.DateTimeOffset, reflectionEntity.DateTimeOffset); - Assert.AreEqual(compiledEntity.DateTimeOffsetN, reflectionEntity.DateTimeOffsetN); - Assert.AreEqual(compiledEntity.DateTimeOffsetNull, reflectionEntity.DateTimeOffsetNull); - Assert.AreEqual(compiledEntity.DateTime, reflectionEntity.DateTime); - Assert.AreEqual(compiledEntity.DateTimeN, reflectionEntity.DateTimeN); - Assert.AreEqual(compiledEntity.DateTimeNull, reflectionEntity.DateTimeNull); - } - - #endregion - - #region Sync - [TestMethod] - [Description("A test to check retrieve functionality APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - // not found - TableResult result = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - result = currentTable.EndExecute(asyncRes); - } - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - result = currentTable.EndExecute(asyncRes); - } - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt["String"], retrievedEntity["String"]); - Assert.AreEqual(sendEnt["Int64"], retrievedEntity["Int64"]); - Assert.AreEqual(sendEnt["LongPrimitive"], retrievedEntity["LongPrimitive"]); - Assert.AreEqual(sendEnt["Int32"], retrievedEntity["Int32"]); - Assert.AreEqual(sendEnt["IntegerPrimitive"], retrievedEntity["IntegerPrimitive"]); - Assert.AreEqual(sendEnt["Guid"], retrievedEntity["Guid"]); - Assert.AreEqual(sendEnt["Double"], retrievedEntity["Double"]); - Assert.AreEqual(sendEnt["DoublePrimitive"], retrievedEntity["DoublePrimitive"]); - Assert.AreEqual(sendEnt["BinaryPrimitive"], retrievedEntity["BinaryPrimitive"]); - Assert.AreEqual(sendEnt["Binary"], retrievedEntity["Binary"]); - Assert.AreEqual(sendEnt["BoolPrimitive"], retrievedEntity["BoolPrimitive"]); - Assert.AreEqual(sendEnt["Bool"], retrievedEntity["Bool"]); - Assert.AreEqual(sendEnt["DateTimeOffsetN"], retrievedEntity["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt["DateTimeOffset"], retrievedEntity["DateTimeOffset"]); - Assert.AreEqual(sendEnt["DateTime"], retrievedEntity["DateTime"]); - Assert.AreEqual(sendEnt["DateTimeN"], retrievedEntity["DateTimeN"]); - } - - - [TestMethod] - [Description("A test to check retrieve functionality APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRetrieveWithResolverAPM() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.PartitionKey = Guid.NewGuid().ToString(); - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - // not found - TableResult result = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - result = currentTable.EndExecute(asyncRes); - } - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - currentTable.Execute(TableOperation.Insert(sendEnt)); - - // Success - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecute(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver), (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - result = currentTable.EndExecute(asyncRes); - } - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)result.Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - #endregion - #endregion - - #region Empty Keys Test - - [TestMethod] - [Description("TableOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationsWithEmptyKeys() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - currentTable.Execute(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - currentTable.Execute(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - currentTable.Execute(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - currentTable.Execute(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - currentTable.Execute(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - currentTable.Execute(TableOperation.Delete(retrievedEntity)); - - // Retrieve Entity - TableResult result2 = currentTable.Execute(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - #endregion - - #region Insert Negative Tests - - [TestMethod] - [Description("TableOperation Insert Entity over 1 MB")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOperationInsertOver1MBSync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("largeprop", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - - OperationContext opContext = new OperationContext(); - try - { - - currentTable.Execute(TableOperation.Insert(ent), null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - #endregion - - #region Serialization/De-serialization tests - - [TestMethod] - [Description("TableOperations with entities not derived from TableEntity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOpsWithNonDerivedEntities() - { - List DTOObjects = new List(new ShapeEntity[3] { new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "square", 4, 4), new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "rectangle", 5, 4), new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "parallelogram", 6, 4) }); - - IEnumerable> azureObjects = DTOObjects.Select(ent => new POCOAdapter(ent, ent.PartitionKey, ent.RowKey)); - - int i = 0; - foreach (POCOAdapter azureObject in azureObjects) - { - IDictionary properties = azureObject.WriteEntity(null); - Assert.AreEqual(3, properties.Count); - Assert.AreEqual(DTOObjects.ElementAt(i).Name, properties["Name"].StringValue); - Assert.AreEqual(DTOObjects.ElementAt(i).Length, properties["Length"].Int32Value); - Assert.AreEqual(DTOObjects.ElementAt(i).Breadth, properties["Breadth"].Int32Value); - - OperationContext context = new OperationContext(); - POCOAdapter ent = new POCOAdapter(new ShapeEntity()); - ent.ReadEntity(properties, context); - Assert.AreEqual(properties["Name"].StringValue, ent.Shape.Name); - Assert.AreEqual(properties["Length"].Int32Value, ent.Shape.Length); - Assert.AreEqual(properties["Breadth"].Int32Value, ent.Shape.Breadth); - i++; - } - } - - [TestMethod] - [Description("Simple test to roundtrip a non derived TableEntity with and without CompiledSerializers")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void SimpleTableEntitySerilization() - { - TableEntity testEnt = new TableEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); - currentTable.Execute(TableOperation.Insert(testEnt)); - TableEntity retrievedEnt = currentTable.Execute(TableOperation.Retrieve(testEnt.PartitionKey, testEnt.RowKey)).Result as TableEntity; - Assert.IsNotNull(retrievedEnt); - - TableEntity.DisableCompiledSerializers = true; - - TableEntity testEnt2 = new TableEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); - currentTable.Execute(TableOperation.Insert(testEnt2)); - TableEntity retrievedEnt2 = currentTable.Execute(TableOperation.Retrieve(testEnt2.PartitionKey, testEnt2.RowKey)).Result as TableEntity; - Assert.IsNotNull(retrievedEnt2); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryGenericTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryGenericTests.cs deleted file mode 100644 index 276d9806c9252..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryGenericTests.cs +++ /dev/null @@ -1,1547 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryGenericTests : TableTestBase - { - #region Locals + Ctors - public TableQueryGenericTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - BaseEntity ent = GenerateRandomEntity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - currentTable.ExecuteBatch(batch); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExists(); - } - - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - #endregion - - #region Unit Tests - - #region Query Segmented - - #region Sync - - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryBasicSync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = currentTable.ExecuteQuerySegmented(query, null); - - foreach (BaseEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithContinuationSync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = currentTable.ExecuteQuerySegmented(query, null, null, opContext); - - int count = 0; - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = currentTable.ExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext); - - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate empty header values")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableEmptyHeaderSigningTest() - { - CloudTableClient client = GenerateCloudTableClient(); - CloudTable currentTable = client.GetTableReference(GenerateRandomTableName()); - OperationContext context = new OperationContext(); - try - { - context.UserHeaders = new Dictionary(); - context.UserHeaders.Add("x-ms-foo", String.Empty); - currentTable.Create(null, context); - DynamicTableEntity ent = new DynamicTableEntity("pk", "rk"); - currentTable.Execute(TableOperation.Insert(ent), null, context); - } - finally - { - currentTable.DeleteIfExists(null, context); - } - } - - #endregion - - #region APM - - [TestMethod] - [Description("A test to validate basic table query APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryBasicAPM() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - foreach (BaseEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithContinuationAPM() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, null, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - int count = 0; - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryBasicTask() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = currentTable.ExecuteQuerySegmentedAsync(query, null).Result; - - foreach (BaseEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithContinuationTask() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext).Result; - - int count = 0; - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext).Result; - - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenCancellationTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - BaseEntity entity = new BaseEntity(partitionKey, rowKey); - entity.ETag = etag; - entity.foo = properties["foo"].StringValue; - entity.A = properties["A"].StringValue; - entity.B = properties["B"].StringValue; - entity.C = properties["C"].StringValue; - entity.D = properties["D"].StringValue; - return entity; - }; - TableContinuationToken token = null; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenRequestOptionsOperationContextTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenCancellationTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - BaseEntity entity = new BaseEntity(partitionKey, rowKey); - entity.ETag = etag; - entity.foo = properties["foo"].StringValue; - entity.A = properties["A"].StringValue; - entity.B = properties["B"].StringValue; - entity.C = properties["C"].StringValue; - entity.D = properties["D"].StringValue; - return entity; - }; - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenRequestOptionsOperationContextCancellationTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenRequestOptionsOperationContextTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - BaseEntity entity = new BaseEntity(partitionKey, rowKey); - entity.ETag = etag; - entity.foo = properties["foo"].StringValue; - entity.A = properties["A"].StringValue; - entity.B = properties["B"].StringValue; - entity.C = properties["C"].StringValue; - entity.D = properties["D"].StringValue; - return entity; - }; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenRequestOptionsOperationContextCancellationTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - BaseEntity entity = new BaseEntity(partitionKey, rowKey); - entity.ETag = etag; - entity.foo = properties["foo"].StringValue; - entity.A = properties["A"].StringValue; - entity.B = properties["B"].StringValue; - entity.C = properties["C"].StringValue; - entity.D = properties["D"].StringValue; - return entity; - }; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (BaseEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - entity.Validate(); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } -#endif - - #endregion - - #endregion - - [TestMethod] - [Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithFilter() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (BaseEntity ent in currentTable.ExecuteQuery(query)) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - ent.Validate(); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryEnumerateTwice() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query); - - List firstIteration = new List(); - List secondIteration = new List(); - - foreach (BaseEntity ent in enumerable) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - firstIteration.Add(ent); - } - - foreach (BaseEntity ent in enumerable) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - secondIteration.Add(ent); - } - - Assert.AreEqual(firstIteration.Count, secondIteration.Count); - - for (int m = 0; m < firstIteration.Count; m++) - { - Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey); - Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey); - Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp); - Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag); - firstIteration[m].Validate(); - } - } - - [TestMethod] - [Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryProjection() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - foreach (BaseEntity ent in currentTable.ExecuteQuery(query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("Basic with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericWithResolver() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - query.TakeCount = 1000; - - foreach (string ent in currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - - foreach (BaseEntity ent in currentTable.ExecuteQuery(query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - - Assert.AreEqual(1000, query.TakeCount); - } - - [TestMethod] - [Description("Basic with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericWithResolverAPM() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - TableContinuationToken token = null; - List list = new List(); - do - { - IAsyncResult result = currentTable.BeginExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TableQuerySegment segment = currentTable.EndExecuteQuerySegmented(result); - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - IAsyncResult result = currentTable.BeginExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => new BaseEntity() - { - PartitionKey = pk, - RowKey = rk, - Timestamp = ts, - A = prop["A"].StringValue, - C = prop["C"].StringValue, - ETag = etag - }, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TableQuerySegment segment = currentTable.EndExecuteQuerySegmented(result); - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - } - -#if TASK - [TestMethod] - [Description("Basic with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericWithResolverTask() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - TableContinuationToken token = null; - List list = new List(); - do - { - TableQuerySegment segment = - currentTable.ExecuteQuerySegmentedAsync( - query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token).Result; - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - TableQuerySegment segment = - currentTable.ExecuteQuerySegmentedAsync( - query, - (pk, rk, ts, prop, etag) => - new BaseEntity() - { - PartitionKey = pk, - RowKey = rk, - Timestamp = ts, - A = prop["A"].StringValue, - C = prop["C"].StringValue, - ETag = etag - }, - token).Result; - - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - - } -#endif - - [TestMethod] - [Description("Basic resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryResolverWithDynamic() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - foreach (string ent in currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - foreach (BaseEntity ent in currentTable.ExecuteQuery(query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("TableQuerySegmented resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQuerySegmentedResolver() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - TableContinuationToken token = null; - List list = new List(); - do - { - TableQuerySegment segment = currentTable.ExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token); - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - TableQuerySegment segment = currentTable.ExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag }, token); - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("TableQuerySegmented resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQuerySegmentedResolverWithDynamic() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - TableContinuationToken token = null; - List list = new List(); - do - { - TableQuerySegment segment = currentTable.ExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token); - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - TableQuerySegment segment = currentTable.ExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag }, token); - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("Basic resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryResolverWithDynamicAPM() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - using (AutoResetEvent waitHandle = new AutoResetEvent(false)) - { - TableContinuationToken token = null; - List list = new List(); - do - { - IAsyncResult result = currentTable.BeginExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TableQuerySegment segment = currentTable.EndExecuteQuerySegmented(result); - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - IAsyncResult result = currentTable.BeginExecuteQuerySegmented(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag }, token, ar => waitHandle.Set(), null); - waitHandle.WaitOne(); - TableQuerySegment segment = currentTable.EndExecuteQuerySegmented(result); - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - } - -#if TASK - [TestMethod] - [Description("Basic resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryResolverWithDynamicTask() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - TableContinuationToken token = null; - List list = new List(); - do - { - TableQuerySegment segment = - currentTable.ExecuteQuerySegmentedAsync( - query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue, token).Result; - list.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (string ent in list) - { - Assert.AreEqual(ent, "ac"); - } - - List list1 = new List(); - do - { - TableQuerySegment segment = - currentTable.ExecuteQuerySegmentedAsync( - query, - (pk, rk, ts, prop, etag) => new BaseEntity() - { - PartitionKey = pk, - RowKey = rk, - Timestamp = ts, - A = prop["A"].StringValue, - C = prop["C"].StringValue, - ETag = etag - }, - token).Result; - - list1.AddRange(segment.Results); - token = segment.ContinuationToken; - } while (token != null); - - foreach (BaseEntity ent in list1) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } -#endif - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryOnSupportedTypes() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - table.Create(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ComplexEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - batch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - table.ExecuteBatch(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.LongPrimitive), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Double), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Int32), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.DateTimeOffset), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.BinaryPrimitive), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithSpecificOnSupportedTypes() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - table.Create(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ComplexEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - batch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - table.ExecuteBatch(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.LongPrimitive), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Double), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Int32), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.DateTimeOffset), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.BinaryPrimitive), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("A test to validate basic take Count with and without continuations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryGenericWithTakeCount() - { - // No continuation - TableQuery query = new TableQuery().Take(100); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 1); - - - // With continuations - query.TakeCount = 1200; - opContext = new OperationContext(); - enumerable = currentTable.ExecuteQuery(query, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate basic take Count with a resolver, with and without continuations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryGenericWithTakeCountAndResolver() - { - // No continuation - TableQuery query = new TableQuery().Take(100); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 1); - - // With continuations - query.TakeCount = 1200; - opContext = new OperationContext(); - enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate EntityActivator can activate internal types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithInternalType() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = currentTable.ExecuteQuerySegmented(query, null); - - foreach (InternalEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - [Description("A test to ensure that a generic query must have a type with a default constructor ")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryOnTypeWithNoCtor() - { - TestHelper.ExpectedException(() => new TableQuery(), "TableQuery should not be able to be instantiated with a generic type that has no default constructor"); - } - #endregion - - #region Negative Tests - - [TestMethod] - [Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteQuerySegmented(query, null, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, table.ExecuteQuery(new TableQuery().Where(filter)).Count()); - } - - private static BaseEntity GenerateRandomEntity(string pk) - { - BaseEntity ent = new BaseEntity(); - ent.Populate(); - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryTests.cs deleted file mode 100644 index 2bbf350dede96..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryTests.cs +++ /dev/null @@ -1,1124 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableQueryTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - DynamicTableEntity ent = GenerateRandomEntity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - currentTable.ExecuteBatch(batch); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExists(); - } - - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Unit Tests - #region Query Segmented - - #region Sync - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryBasicSync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - query.TakeCount = 100; - - TableQuerySegment seg = currentTable.ExecuteQuerySegmented(query, null); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - Assert.AreEqual(100, query.TakeCount); - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithContinuationSync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = currentTable.ExecuteQuerySegmented(query, null, null, opContext); - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = currentTable.ExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext); - seg.ContinuationToken = null; - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion - - #region APM - - [TestMethod] - [Description("A test to validate basic table query APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryBasicAPM() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithContinuationAPM() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, null, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = currentTable.EndExecuteQuerySegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion - - #region Task - -#if TASK - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryBasicTask() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - query.TakeCount = 100; - - TableQuerySegment seg = currentTable.ExecuteQuerySegmentedAsync(query, null).Result; - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - Assert.AreEqual(100, query.TakeCount); - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithContinuationTask() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext).Result; - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext).Result; - seg.ContinuationToken = null; - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenCancellationTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - return new DynamicTableEntity(partitionKey, rowKey, timestamp, etag, properties); - }; - TableContinuationToken token = null; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenRequestOptionsOperationContextTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenCancellationTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - return new DynamicTableEntity(partitionKey, rowKey, timestamp, etag, properties); - }; - TableContinuationToken token = null; - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryTokenRequestOptionsOperationContextCancellationTokenTask() - { - TableQuery query = new TableQuery(); - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, token, requestOptions, operationContext, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenRequestOptionsOperationContextTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - return new DynamicTableEntity(partitionKey, rowKey, timestamp, etag, properties); - }; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } - - [TestMethod] - [Description("Test Table ExecuteQuerySegmented - Task")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableExecuteQuerySegmentedQueryResolverTokenRequestOptionsOperationContextCancellationTokenTask() - { - TableQuery query = new TableQuery(); - EntityResolver resolver = (partitionKey, rowKey, timestamp, properties, etag) => - { - return new DynamicTableEntity(partitionKey, rowKey, timestamp, etag, properties); - }; - TableContinuationToken token = null; - TableRequestOptions requestOptions = new TableRequestOptions(); - OperationContext operationContext = new OperationContext(); - CancellationToken cancellationToken = CancellationToken.None; - - int count = 0; - do - { - TableQuerySegment querySegment = currentTable.ExecuteQuerySegmentedAsync(query, resolver, token, requestOptions, operationContext, cancellationToken).Result; - token = querySegment.ContinuationToken; - - foreach (DynamicTableEntity entity in querySegment) - { - Assert.IsTrue(entity.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(entity.Properties.Count, 4); - ++count; - } - } - while (token != null); - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(operationContext, 2); - } -#endif - - #endregion - - #endregion - - [TestMethod] - [Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithFilter() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (DynamicTableEntity ent in currentTable.ExecuteQuery(query)) - { - Assert.AreEqual(ent.Properties["foo"].StringValue, "bar"); - - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryEnumerateTwice() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query); - - List firstIteration = new List(); - List secondIteration = new List(); - - foreach (DynamicTableEntity ent in enumerable) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - firstIteration.Add(ent); - } - - foreach (DynamicTableEntity ent in enumerable) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - secondIteration.Add(ent); - } - - Assert.AreEqual(firstIteration.Count, secondIteration.Count); - - for (int m = 0; m < firstIteration.Count; m++) - { - Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey); - Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey); - Assert.AreEqual(firstIteration[m].Properties.Count, secondIteration[m].Properties.Count); - Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp); - Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag); - } - } - - [TestMethod] - [Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryProjection() - { - TableQuery query = new TableQuery().Select(new List() { "a", "c" }); - - foreach (DynamicTableEntity ent in currentTable.ExecuteQuery(query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.Properties["a"].StringValue, "a"); - Assert.IsFalse(ent.Properties.ContainsKey("b")); - Assert.AreEqual(ent.Properties["c"].StringValue, "c"); - Assert.IsFalse(ent.Properties.ContainsKey("d")); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryOnSupportedTypes() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - table.Create(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - table.ExecuteBatch(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["BinaryPrimitive"].BinaryValue), 50); - - - } - finally - { - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableRegionalQueryOnSupportedTypes() - { - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); - - CloudTableClient client = GenerateCloudTableClient(); - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - - try - { - table.Create(); - - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - table.ExecuteBatch(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef["BinaryPrimitive"].BinaryValue), 50); - - - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - table.DeleteIfExists(); - } - } - - [TestMethod] - [Description("A test to validate querying with an empty value")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryEmptyValue() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - table.Create(); - - // Setup - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey"); - dynEnt.Properties.Add("A", new EntityProperty(string.Empty)); - table.Execute(TableOperation.Insert(dynEnt)); - - // 1. Filter on String - List results = table.ExecuteQuery(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty))).ToList(); - Assert.AreEqual(1, results.Count); - - List pocoresults = table.ExecuteQuery(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty))).ToList(); - Assert.AreEqual(1, pocoresults.Count); - } - - [TestMethod] - [Description("A test to validate basic take Count with and without continuations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithTakeCount() - { - // No continuation - TableQuery query = new TableQuery().Take(100); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 1); - - // With continuations - query.TakeCount = 1200; - opContext = new OperationContext(); - enumerable = currentTable.ExecuteQuery(query, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate basic take Count with a resolver, with and without continuations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithTakeCountAndResolver() - { - // No continuation - TableQuery query = new TableQuery().Take(100); - - OperationContext opContext = new OperationContext(); - IEnumerable enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 1); - - // With continuations - query.TakeCount = 1200; - opContext = new OperationContext(); - enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); - - Assert.AreEqual(query.TakeCount, enumerable.Count()); - TestHelper.AssertNAttempts(opContext, 2); - } - - #endregion - - #region Negative Tests - - [TestMethod] - [Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - currentTable.ExecuteQuerySegmented(query, null, null, opContext); - Assert.Fail(); - } - catch (StorageException) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, table.ExecuteQuery(new TableQuery().Where(filter)).Count()); - } - - private static DynamicTableEntity GenerateRandomEntity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("a", new EntityProperty("a")); - ent.Properties.Add("b", new EntityProperty("b")); - ent.Properties.Add("c", new EntityProperty("c")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryableTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryableTests.cs deleted file mode 100644 index fd2ba4f67bb62..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableQueryableTests.cs +++ /dev/null @@ -1,2099 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Storage.RetryPolicies; -using Microsoft.WindowsAzure.Storage.Table.DataServices; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using Microsoft.WindowsAzure.Storage.Table.Queryable; -using Microsoft.WindowsAzure.Test.Network; -using Microsoft.WindowsAzure.Test.Network.Behaviors; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryableTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableQueryableTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - static CloudTable complexEntityTable = null; - static ComplexEntity middleRef = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExists(); - - // Bulk Query Entities - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - var ent = GenerateRandomEnitity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - - batch.Insert(ent); - } - - currentTable.ExecuteBatch(batch); - } - - complexEntityTable = tableClient.GetTableReference(GenerateRandomTableName()); - complexEntityTable.Create(); - - // Setup - TableBatchOperation complexBatch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.Int32N = m; - complexEntity.IntegerPrimitive = m; - complexEntity.IntegerPrimitiveN = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.LongPrimitiveN = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - complexBatch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - complexEntityTable.ExecuteBatch(complexBatch); - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExists(); - complexEntityTable.DeleteIfExists(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Unit Tests - #region Query Segmented - - #region Sync - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableExecuteQueryGeneric() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference(GenerateRandomTableName()); - table.CreateIfNotExists(); - - BaseEntity entity = new BaseEntity("mypk", "myrk"); - TableOperation operation = TableOperation.Insert(entity); - table.Execute(operation); - - IQueryable query = table.CreateQuery().Where(x => x.PartitionKey == "mypk"); - foreach (BaseEntity ent in query.ToList()) - { - Assert.AreEqual("mypk", ent.PartitionKey); - } - - IEnumerable entities1 = GetEntities(table, "mypk"); - foreach (BaseEntity ent in entities1) - { - Assert.AreEqual("mypk", ent.PartitionKey); - } - - } - - private IEnumerable GetEntities(CloudTable table, string id) where T : ITableEntity, new() - { - IQueryable query = table.CreateQuery() - .Where(x => x.PartitionKey == "mypk"); - return query.ToList(); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableExecuteQuerySync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - IEnumerable seg = query.Execute(); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuery(query).ToList(); - - foreach (DynamicTableEntity ent in segList) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableExecuteQueryWithResolverSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue).AsTableQuery(); - - IEnumerable seg = query.Execute(); - - int count = 0; - foreach (string ent in seg) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - - TableQuery query2 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuery(query2, (pk, rk, ts, props, etag) => props["a"].StringValue).ToList(); - - count = 0; - foreach (string ent in segList) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBasicSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - TableQuerySegment seg = query.ExecuteSegmented(null); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuerySegmented(query, null).ToList(); - - foreach (DynamicTableEntity ent in segList) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBasicWithResolverSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue).AsTableQuery(); - - TableQuerySegment seg = query.ExecuteSegmented(null); - - int count = 0; - foreach (string ent in seg) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - - TableQuery query2 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuerySegmented(query2, (pk, rk, ts, props, etag) => props["a"].StringValue, null).ToList(); - - count = 0; - foreach (string ent in segList) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic binary comparison operators")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBinaryOperatorsSync() - { - // == - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - IEnumerable seg = query.Execute(); - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - Assert.AreEqual(100, count); - - // != - TableQuery query2 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey != "0050" - select ent).AsTableQuery(); - IEnumerable seg2 = query2.Execute(); - count = 0; - foreach (DynamicTableEntity ent in seg2) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreEqual(4, ent.Properties.Count); - Assert.AreNotEqual("0050", ent.RowKey); - count++; - } - Assert.AreEqual(99, count); - - // < - TableQuery query3 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") < 0 - select ent).AsTableQuery(); - IEnumerable seg3 = query3.Execute(); - count = 0; - foreach (DynamicTableEntity ent in seg3) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreEqual(4, ent.Properties.Count); - Assert.AreNotEqual("0050", ent.RowKey); - count++; - } - Assert.AreEqual(50, count); - - // > - TableQuery query4 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") > 0 - select ent).AsTableQuery(); - IEnumerable seg4 = query4.Execute(); - count = 0; - foreach (DynamicTableEntity ent in seg4) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreEqual(4, ent.Properties.Count); - Assert.AreNotEqual("0050", ent.RowKey); - count++; - } - Assert.AreEqual(49, count); - - // >= - TableQuery query5 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") >= 0 - select ent).AsTableQuery(); - IEnumerable seg5 = query5.Execute(); - bool flag = false; - count = 0; - foreach (DynamicTableEntity ent in seg5) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreEqual(4, ent.Properties.Count); - count++; - if (ent.RowKey == "0050") - { - flag = true; - } - } - Assert.AreEqual(50, count); - Assert.IsTrue(flag); - - // <= - TableQuery query6 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") <= 0 - select ent).AsTableQuery(); - IEnumerable seg6 = query6.Execute(); - count = 0; - flag = false; - foreach (DynamicTableEntity ent in seg6) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreEqual(4, ent.Properties.Count); - count++; - if (ent.RowKey == "0050") - { - flag = true; - } - } - Assert.AreEqual(51, count); - Assert.IsTrue(flag); - - // + - TableQuery query7 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < 1 + 50 - select ent).AsTableQuery(); - IEnumerable seg7 = query7.Execute(); - Assert.AreEqual(51, seg7.Count()); - - // - - TableQuery query8 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < 100 - 50 - select ent).AsTableQuery(); - IEnumerable seg8 = query8.Execute(); - Assert.AreEqual(50, seg8.Count()); - - // * - TableQuery query9 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < 2 * 25 - select ent).AsTableQuery(); - IEnumerable seg9 = query9.Execute(); - Assert.AreEqual(50, seg9.Count()); - - // / - TableQuery query10 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < 100 / 2 - select ent).AsTableQuery(); - IEnumerable seg10 = query10.Execute(); - Assert.AreEqual(50, seg10.Count()); - - // % - TableQuery query11 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < 100 % 12 - select ent).AsTableQuery(); - IEnumerable seg11 = query11.Execute(); - Assert.AreEqual(4, seg11.Count()); - - // left shift - TableQuery query12 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < (1 << 2) - select ent).AsTableQuery(); - IEnumerable seg12 = query12.Execute(); - Assert.AreEqual(4, seg12.Count()); - - // right shift - TableQuery query13 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) < (8 >> 1) - select ent).AsTableQuery(); - IEnumerable seg13 = query13.Execute(); - Assert.AreEqual(4, seg13.Count()); - - // & - TableQuery query14 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) > (2 & 4) - select ent).AsTableQuery(); - IEnumerable seg14 = query14.Execute(); - Assert.AreEqual(99, seg14.Count()); - - // | - TableQuery query15 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) > (2 | 4) - select ent).AsTableQuery(); - IEnumerable seg15 = query15.Execute(); - Assert.AreEqual(93, seg15.Count()); - } - - [TestMethod] - [Description("IQueryable - A test to validate filter combinations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableCombineFilters() - { - OperationContext opContext = new OperationContext(); - - TableQuery res = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") >= 0) || - (ent.PartitionKey == "tables_batch_2" && ent.RowKey.CompareTo("0050") >= 0) - select ent).WithContext(opContext); - - int count = 0; - foreach (DynamicTableEntity ent in res) - { - Assert.AreEqual(ent.Properties["test"].StringValue, "test"); - Assert.IsTrue(ent.RowKey.CompareTo("0050") >= 0); - count++; - } - - Assert.AreEqual(100, count); - - TableQuery res2 = (from ent in currentTable.CreateQuery() - where ((ent.RowKey.CompareTo("0050") == 0 ||ent.RowKey.CompareTo("0051") == 0) && ent.PartitionKey == "tables_batch_2") - select ent).WithContext(opContext); - count = 0; - foreach (DynamicTableEntity ent in res2) - { - count++; - Assert.AreEqual("tables_batch_2", ent.PartitionKey); - } - - Assert.AreEqual(2, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate First and FirstOrDefault")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableFirst() - { - DynamicTableEntity res = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") < 0) - select ent).First(); - Assert.AreEqual("tables_batch_1", res.PartitionKey); - Assert.AreEqual("0000", res.RowKey); - - DynamicTableEntity res2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") < 0) - select ent).FirstOrDefault(); - Assert.AreEqual("tables_batch_1", res2.PartitionKey); - Assert.AreEqual("0000", res2.RowKey); - - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_16" && ent.RowKey.CompareTo("0050") < 0) - select ent).First(), "Invoking First on a query that does not give any results should fail"); - - DynamicTableEntity res3 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_16" && ent.RowKey.CompareTo("0050") < 0) - select ent).FirstOrDefault(); - Assert.IsNull(res3); - } - - [TestMethod] - [Description("IQueryable - A test to validate Single and SingleOrDefault")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableSingle() - { - DynamicTableEntity res = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") == 0) - select ent).Single(); - Assert.AreEqual("tables_batch_1", res.PartitionKey); - Assert.AreEqual("0050", res.RowKey); - - DynamicTableEntity res2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") == 0) - select ent).SingleOrDefault(); - Assert.AreEqual("tables_batch_1", res2.PartitionKey); - Assert.AreEqual("0050", res2.RowKey); - - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_16" && ent.RowKey.CompareTo("0050") == 0) - select ent).Single(), "Invoking Single on a query that does not return anything should fail"); - - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Single(), "Invoking Single on a query that returns more than one result should fail"); - - DynamicTableEntity res3 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_16" && ent.RowKey.CompareTo("0050") == 0) - select ent).SingleOrDefault(); - Assert.IsNull(res3); - } - - [TestMethod] - [Description("IQueryable - A test to validate Take")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableTake() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") == 0) - select ent).Take(1); - Assert.AreEqual(1, query.ToList().Count); - - IQueryable query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(5); - Assert.AreEqual(5, query2.ToList().Count); - - IQueryable query3 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(51); - // If we do a Take with more than result number of entities, we just get the max. No error is thrown. - Assert.AreEqual(49, query3.ToList().Count); - } - - [TestMethod] - [Description("IQueryable - A test to validate multiple Take options")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableMultipleTake() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(5).Take(1); - Assert.AreEqual(1, query.ToList().Count); - - IQueryable query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(1).Take(5); - // Should still give just 1. - Assert.AreEqual(1, query2.ToList().Count); - - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") == 0) - select ent).Take(1).Take(-1).ToList(), "Negative Take count should fail"); - } - - [TestMethod] - [Description("IQueryable - A test to validate Cast")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableCast() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Cast(); - int count = 0; - foreach (POCOEntity ent in query) - { - Assert.AreEqual("a", ent.a); - Assert.AreEqual("b", ent.b); - Assert.AreEqual("c", ent.c); - Assert.AreEqual("test", ent.test); - count++; - } - Assert.AreEqual(49, count); - - IQueryable query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Cast(); - int count2 = 0; - foreach (ProjectedPOCO ent in query2) - { - Assert.AreEqual("a", ent.a); - Assert.AreEqual("b", ent.b); - Assert.AreEqual("c", ent.c); - Assert.IsNull(ent.d); - Assert.AreEqual("test", ent.test); - count2++; - } - Assert.AreEqual(49, count2); - } - - [TestMethod] - [Description("IQueryable - A test to validate multiple Cast options")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableMultipleCast() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Cast().Cast(); - int count = 0; - foreach (ProjectedPOCO ent in query) - { - Assert.AreEqual("a", ent.a); - Assert.AreEqual("b", ent.b); - Assert.AreEqual("c", ent.c); - Assert.IsNull(ent.d); - Assert.AreEqual("test", ent.test); - count++; - } - Assert.AreEqual(49, count); - - IQueryable query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Cast().Cast(); - int count2 = 0; - foreach (POCOEntity ent in query2) - { - Assert.AreEqual("a", ent.a); - Assert.AreEqual("b", ent.b); - Assert.AreEqual("c", ent.c); - Assert.AreEqual("test", ent.test); - count2++; - } - Assert.AreEqual(49, count2); - } - - [TestMethod] - [Description("IQueryable - A test to validate ToArray")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableToArray() - { - DynamicTableEntity[] query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") == 0) - select ent).Take(1).ToArray(); - - Assert.AreEqual(1, query.Length); - - DynamicTableEntity[] query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(5).ToArray(); - Assert.AreEqual(5, query2.Length); - - DynamicTableEntity[] query3 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Take(51).ToArray(); - // If we do a Take with more than result number of entities, we just get the max. No error is thrown. - Assert.AreEqual(49, query3.Length); - } - - [TestMethod] - [Description("IQueryable - A test to use a filter and a predicate")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableFilterPredicate() - { - // Filter before key predicate. - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.RowKey != "0050" && ent.PartitionKey == "tables_batch_1") - select ent); - int count = 0; - foreach (DynamicTableEntity ent in query) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreNotEqual("0050", ent.RowKey); - count++; - } - Assert.AreEqual(99, count); - - // Key predicate before filter. - IQueryable query2 = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey != "0050") - select ent); - int count2 = 0; - foreach (DynamicTableEntity ent in query2) - { - Assert.AreEqual("tables_batch_1", ent.PartitionKey); - Assert.AreNotEqual("0050", ent.RowKey); - count2++; - } - Assert.AreEqual(99, count2); - } - - [TestMethod] - [Description("IQueryable - A test to use a complex expression filter")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableComplexFilter() - { - IQueryable query = (from ent in complexEntityTable.CreateQuery() - where ((ent.RowKey == "0050" && ent.Int32 == 50) || ((ent.Int32 == 30) && (ent.String == "wrong string" || ent.Bool == true)) || (ent.LongPrimitiveN == (long)int.MaxValue + 50)) - select ent); - int count = 0; - foreach (ComplexEntity ent in query) - { - count++; - Assert.IsTrue(ent.Int32 == 50 || ent.Int32 == 30); - } - - Assert.AreEqual(2, count); - } - - [TestMethod] - [Description("IQueryable - A test to use a complex expression filter consisting of multiple nested paranthesis")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableNestedParanthesis() - { - IQueryable query = (from ent in complexEntityTable.CreateQuery() - where ((ent.RowKey == "0050" && ent.Int32 == 50) || - ((ent.Int32 == 30) && (ent.String == "wrong string" || ent.Bool == true) && !(ent.IntegerPrimitive == 31 && ent.LongPrimitive == (long)int.MaxValue + 31)) || - (ent.LongPrimitiveN == (long)int.MaxValue + 50)) - select ent); - int count = 0; - foreach (ComplexEntity ent in query) - { - count++; - Assert.IsTrue(ent.Int32 == 50 || ent.Int32 == 30); - } - - Assert.AreEqual(2, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate Unary operators")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableUnary() - { - OperationContext opContext = new OperationContext(); - - // Not. - TableQuery res = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && - !(ent.RowKey.CompareTo("0050") == 0)) - select ent).WithContext(opContext); - IEnumerable queryResult = res.Execute(); - Assert.AreEqual(99, queryResult.Count()); - foreach (DynamicTableEntity ent in queryResult) - { - Assert.AreNotEqual("0050", ent.RowKey); - } - - // Unary +. - TableQuery query = (from ent in complexEntityTable.CreateQuery() - where +(ent.Int32) < +50 - select ent).AsTableQuery(); - IEnumerable seg = query.Execute(); - Assert.AreEqual(50, seg.Count()); - - // Unary -. - TableQuery query2 = (from ent in complexEntityTable.CreateQuery() - where (ent.Int32) > -1 - select ent).AsTableQuery(); - IEnumerable seg2 = query2.Execute(); - Assert.AreEqual(100, seg2.Count()); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithContinuationSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - select ent).AsTableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = query.ExecuteSegmented(null, null, opContext); - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = query.ExecuteSegmented(seg.ContinuationToken, null, opContext); - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - #endregion - - #region APM - [TestMethod] - [Description("IQueryable - A test to validate basic table query APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryableBasicAPM() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - List segList = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query, null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - segList = currentTable.EndExecuteQuerySegmented(asyncRes).ToList(); - } - - foreach (DynamicTableEntity ent in segList) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryableBasicWithResolverAPM() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue).AsTableQuery(); - - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - int count = 0; - foreach (string ent in seg) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - - TableQuery query2 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - List segList = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - currentTable.BeginExecuteQuerySegmented(query2, (pk, rk, ts, props, etag) => props["a"].StringValue, null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - segList = currentTable.EndExecuteQuerySegmented(asyncRes).ToList(); - } - - count = 0; - foreach (string ent in segList) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table continuation APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryableWithContinuationAPM() - { - TableQuery query = (from ent in currentTable.CreateQuery() - select ent).AsTableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(null, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(seg.ContinuationToken, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion - - #region Task - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBasicTask() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - TableQuerySegment seg = query.ExecuteSegmentedAsync(null).Result; - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuerySegmentedAsync(query, null).Result.ToList(); - - foreach (DynamicTableEntity ent in segList) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBasicWithResolverTask() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue).AsTableQuery(); - - TableQuerySegment seg = query.ExecuteSegmentedAsync(null).Result; - - int count = 0; - foreach (string ent in seg) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - - TableQuery query2 = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - // Try running the query on the Table object. - List segList = currentTable.ExecuteQuerySegmentedAsync(query2, (pk, rk, ts, props, etag) => props["a"].StringValue, null).Result.ToList(); - - count = 0; - foreach (string ent in segList) - { - Assert.AreEqual("a", ent); - count++; - } - - Assert.AreEqual(100, count); - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithContinuationTask() - { - TableQuery query = (from ent in currentTable.CreateQuery() - select ent).AsTableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = query.ExecuteSegmentedAsync(null, null, opContext).Result; - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = query.ExecuteSegmentedAsync(seg.ContinuationToken, null, opContext).Result; - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - #endregion - - #endregion - - [TestMethod] - [Description("IQueryable DynamicTableEntityQuery")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableDynamicTableEntityQuery() - { - OperationContext opContext = new OperationContext(); - - Func identityFunc = (s) => s; - - TableQuery res = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.Properties[identityFunc("DateTimeOffset")].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent).WithContext(opContext); - - List entities = res.ToList(); - - Assert.AreEqual(entities.Count, 50); - } - - [TestMethod] - [Description("IQueryable Validate multiple WithContext options")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableMultipleContexts() - { - OperationContext opContext = new OperationContext(); - OperationContext opContext2 = new OperationContext(); - - opContext.UserHeaders = new Dictionary(); - opContext.UserHeaders.Add("foo", "bar"); - opContext2.UserHeaders = new Dictionary(); - opContext2.UserHeaders.Add("hello", "world"); - Func identityFunc = (s) => s; - - TableQuery res = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey - select ent).WithContext(opContext).WithContext(opContext2); - - Action act = () => res.ToList(); - TestHelper.VerifyHeaderWasSent(opContext2.UserHeaders.Keys.First(), opContext2.UserHeaders[opContext2.UserHeaders.Keys.First()], XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), act); - TestHelper.VerifyHeaderWasSent(opContext.UserHeaders.Keys.First(), String.Empty, XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), act); - } - - [TestMethod] - [Description("IQueryable Validate WithOptions")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithOptions() - { - TableRequestOptions options = new TableRequestOptions(); - options.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 4); - - TableRequestOptions options2 = new TableRequestOptions(); - options2.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(1), 2); - - TestHelper.ExecuteMethodWithRetry( - 5, - new[] { - //Insert upstream network delay to prevent upload to server @ 10000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), - new BehaviorOptions(4)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), - new BehaviorOptions(4)) - }, - (option, context) => (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey - select ent).WithOptions(options).AsTableQuery().Execute((TableRequestOptions)option, context).ToList() - ); - - TestHelper.ExecuteMethodWithRetry( - 3, - new[] { - //Insert upstream network delay to prevent upload to server @ 10000ms / kb - PerformanceBehaviors.InsertUpstreamNetworkDelay(10000, - XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), - new BehaviorOptions(2)), - // After 100 ms return throttle message - DelayedActionBehaviors.ExecuteAfter(Actions.ThrottleTableRequest, - 100, - XStoreSelectors.TableTraffic().IfHostNameContains(currentTable.ServiceClient.Credentials.AccountName), - new BehaviorOptions(2)) - }, - (option, context) => (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey - select ent).WithOptions(options).WithOptions(options2).AsTableQuery().Execute((TableRequestOptions)option, context).ToList() - ); - } - - [TestMethod] - [Description("IQueryable Where")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWhere() - { - OperationContext opContext = new OperationContext(); - - TableQuery res = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") >= 0 - select ent).WithContext(opContext); - - int count = 0; - foreach (DynamicTableEntity ent in res) - { - Assert.AreEqual(ent.Properties["test"].StringValue, "test"); - - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("IQueryable - A test to validate a query with multiple where clauses")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableMultipleWhereSync() - { - OperationContext opContext = new OperationContext(); - - TableQuery res = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - where ent.RowKey.CompareTo("0050") >= 0 - select ent).WithContext(opContext); - - int count = 0; - foreach (DynamicTableEntity ent in res) - { - Assert.AreEqual(ent.Properties["test"].StringValue, "test"); - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("TableQueryable - A test to validate basic table continuation & query is able to correctly execute multiple times")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableEnumerateTwice() - { - OperationContext opContext = new OperationContext(); - TableQuery res = (from ent in currentTable.CreateQuery() - select ent).WithContext(opContext); - - List firstIteration = new List(); - List secondIteration = new List(); - - foreach (DynamicTableEntity ent in res) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - firstIteration.Add(ent); - } - - foreach (DynamicTableEntity ent in res) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - secondIteration.Add(ent); - } - - Assert.AreEqual(firstIteration.Count, secondIteration.Count); - - for (int m = 0; m < firstIteration.Count; m++) - { - Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey); - Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey); - Assert.AreEqual(firstIteration[m].Properties.Count, secondIteration[m].Properties.Count); - Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp); - Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag); - } - } - - [TestMethod] - [Description("IQueryable Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableProjection() - { - OperationContext opContext = new OperationContext(); - var baseQuery = currentTable.CreateQuery().WithContext(opContext); - - var pocoRes = (from ent in baseQuery - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }); - int count = 0; - - foreach (ProjectedPOCO ent in pocoRes) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.a, "a"); - Assert.IsNull(ent.b); - Assert.AreEqual(ent.c, "c"); - Assert.IsNull(ent.d); - count++; - } - - // Project a single property via Select - var stringRes = (from ent in baseQuery - select ent.b).ToList(); - - Assert.AreEqual(stringRes.Count, count); - - // Project a single property and modify it via Select - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey == "0050" - select (ent.Int32 + 1)).Single(), "Specifying any operation after last navigation other than take should fail"); - - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") > 0 - select ent.Int32).Skip(5).Single(), "Specifying any operation after last navigation other than take should fail"); - - // TableQuery.Project no resolver - IQueryable projectionResult = (from ent in baseQuery - select TableQuery.Project(ent, "a", "b")); - count = 0; - foreach (POCOEntity ent in projectionResult) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.a, "a"); - Assert.AreEqual(ent.b, "b"); - Assert.IsNull(ent.c); - Assert.IsNull(ent.test); - count++; - } - - Assert.AreEqual(stringRes.Count, count); - - // TableQuery.Project with resolver - IQueryable resolverRes = (from ent in baseQuery - select TableQuery.Project(ent, "a", "b")).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue); - count = 0; - foreach (string s in resolverRes) - { - Assert.AreEqual(s, "a"); - count++; - } - - Assert.AreEqual(stringRes.Count, count); - - // Project multiple properties via Select - IEnumerable> result = (from ent in baseQuery - select new Tuple - ( - ent.a, - ent.b - )).ToList(); - - count = 0; - foreach (Tuple entTuple in (IEnumerable>)result) - { - Assert.AreEqual("a", entTuple.Item1); - Assert.AreEqual("b", entTuple.Item2); - count++; - } - - Assert.AreEqual(1500, count); - - // Project with query options - TableQuery queryOptionsResult = (from ent in baseQuery - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }).AsTableQuery(); - - count = 0; - foreach (ProjectedPOCO ent in queryOptionsResult) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.a, "a"); - Assert.IsNull(ent.b); - Assert.AreEqual(ent.c, "c"); - Assert.IsNull(ent.d); - count++; - } - Assert.AreEqual(49, count); - - // Project to an anonymous type - var anonymousRes = (from ent in baseQuery - select new - { - a = ent.a, - b = ent.b - }); - Assert.AreEqual(1500, anonymousRes.ToList().Count); - - // Project with resolver - IQueryable resolverResult = (from ent in baseQuery - select new ProjectedPOCO() - { - a = ent.a, - c = ent.c - }).AsTableQuery().Resolve((pk, rk, ts, props, etag) => props["a"].StringValue); - count = 0; - foreach (string s in resolverResult) - { - Assert.AreEqual(s, "a"); - count++; - } - - Assert.AreEqual(stringRes.Count, count); - - // Single with entity types - ProjectedPOCO singleRes = (from ent in baseQuery - where ent.PartitionKey == "tables_batch_1" && ent.RowKey == "0050" - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }).Single(); - - Assert.AreEqual("a", singleRes.a); - Assert.IsNull(singleRes.b); - Assert.AreEqual("c", singleRes.c); - Assert.IsNull(singleRes.d); - Assert.AreEqual("0050", singleRes.RowKey); - - // SingleOrDefault - ProjectedPOCO singleOrDefaultRes = (from ent in baseQuery - where ent.PartitionKey == "tables_batch_1" && ent.RowKey == "0050" - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }).SingleOrDefault(); - - Assert.AreEqual("a", singleOrDefaultRes.a); - Assert.IsNull(singleOrDefaultRes.b); - Assert.AreEqual("c", singleOrDefaultRes.c); - Assert.IsNull(singleOrDefaultRes.d); - Assert.AreEqual("0050", singleOrDefaultRes.RowKey); - - // First with entity types - ProjectedPOCO firstRes = (from ent in baseQuery - where ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0 - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }).First(); - - Assert.AreEqual("a", firstRes.a); - Assert.IsNull(firstRes.b); - Assert.AreEqual("c", firstRes.c); - Assert.IsNull(firstRes.d); - Assert.AreEqual("0051", firstRes.RowKey); - - // FirstOrDefault with entity types - ProjectedPOCO firstOrDefaultRes = (from ent in baseQuery - where ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0 - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }).FirstOrDefault(); - - Assert.AreEqual("a", firstOrDefaultRes.a); - Assert.IsNull(firstOrDefaultRes.b); - Assert.AreEqual("c", firstOrDefaultRes.c); - Assert.IsNull(firstOrDefaultRes.d); - Assert.AreEqual("0051", firstOrDefaultRes.RowKey); - } - - [TestMethod] - [Description("IQueryable - validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableOnSupportedTypes() - { - // 1. Filter on String - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.String.CompareTo("0050") >= 0 - select ent); - - Assert.AreEqual(50, stringQuery.AsTableQuery().Execute().Count()); - - // 2. Filter on Guid - var guidQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Guid == middleRef.Guid - select ent); - - Assert.AreEqual(1, guidQuery.AsTableQuery().Execute().Count()); - - // 3. Filter on Long - var longQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Int64 >= middleRef.Int64 - select ent); - - Assert.AreEqual(50, longQuery.AsTableQuery().Execute().Count()); - - var longPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.LongPrimitive >= middleRef.LongPrimitive - select ent); - - Assert.AreEqual(50, longPrimitiveQuery.AsTableQuery().Execute().Count()); - - var longNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.LongPrimitiveN >= middleRef.LongPrimitiveN - select ent); - - Assert.AreEqual(50, longNullableQuery.AsTableQuery().Execute().Count()); - - // 4. Filter on Double - var doubleQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Double >= middleRef.Double - select ent); - - Assert.AreEqual(50, doubleQuery.AsTableQuery().Execute().Count()); - - var doubleNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.DoublePrimitive >= middleRef.DoublePrimitive - select ent); - - Assert.AreEqual(50, doubleNullableQuery.AsTableQuery().Execute().Count()); - - // 5. Filter on Integer - var int32Query = (from ent in complexEntityTable.CreateQuery() - where ent.Int32 >= middleRef.Int32 - select ent); - - Assert.AreEqual(50, int32Query.AsTableQuery().Execute().Count()); - - var int32NullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Int32N >= middleRef.Int32N - select ent); - - Assert.AreEqual(50, int32NullableQuery.AsTableQuery().Execute().Count()); - - // 6. Filter on Date - var dtoQuery = (from ent in complexEntityTable.CreateQuery() - where ent.DateTimeOffset >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, dtoQuery.AsTableQuery().Execute().Count()); - - // 7. Filter on Boolean - var boolQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Bool == middleRef.Bool - select ent); - - Assert.AreEqual(50, boolQuery.AsTableQuery().Execute().Count()); - - var boolPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.BoolPrimitive == middleRef.BoolPrimitive - select ent); - - Assert.AreEqual(50, boolPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 8. Filter on Binary - var binaryQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Binary == middleRef.Binary - select ent); - - Assert.AreEqual(1, binaryQuery.AsTableQuery().Execute().Count()); - - var binaryPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.BinaryPrimitive == middleRef.BinaryPrimitive - select ent); - - Assert.AreEqual(1, binaryPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 10. Complex Filter on Binary GTE - - var complexFilter = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.String.CompareTo("0050") >= 0 && - ent.Int64 >= middleRef.Int64 && - ent.LongPrimitive >= middleRef.LongPrimitive && - ent.LongPrimitiveN >= middleRef.LongPrimitiveN && - ent.Int32 >= middleRef.Int32 && - ent.Int32N >= middleRef.Int32N && - ent.DateTimeOffset >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, complexFilter.AsTableQuery().Execute().Count()); - } - - [TestMethod] - [Description("IQueryable - validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableOnSupportedTypesViaDynamicTableEntity() - { - // 1. Filter on String - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["String"].StringValue.CompareTo("0050") >= 0 - select ent); - - Assert.AreEqual(50, stringQuery.AsTableQuery().Execute().Count()); - - // 2. Filter on Guid - var guidQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Guid"].GuidValue == middleRef.Guid - select ent); - - Assert.AreEqual(1, guidQuery.AsTableQuery().Execute().Count()); - - // 3. Filter on Long - var longQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int64"].Int64Value >= middleRef.Int64 - select ent); - - Assert.AreEqual(50, longQuery.AsTableQuery().Execute().Count()); - - var longPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["LongPrimitive"].Int64Value >= middleRef.LongPrimitive - select ent); - - Assert.AreEqual(50, longPrimitiveQuery.AsTableQuery().Execute().Count()); - - var longNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["LongPrimitiveN"].Int64Value >= middleRef.LongPrimitiveN - select ent); - - Assert.AreEqual(50, longNullableQuery.AsTableQuery().Execute().Count()); - - // 4. Filter on Double - var doubleQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Double"].DoubleValue >= middleRef.Double - select ent); - - Assert.AreEqual(50, doubleQuery.AsTableQuery().Execute().Count()); - - var doubleNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["DoublePrimitive"].DoubleValue >= middleRef.DoublePrimitive - select ent); - - Assert.AreEqual(50, doubleNullableQuery.AsTableQuery().Execute().Count()); - - // 5. Filter on Integer - var int32Query = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int32"].Int32Value >= middleRef.Int32 - select ent); - - Assert.AreEqual(50, int32Query.AsTableQuery().Execute().Count()); - - var int32NullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int32N"].Int32Value >= middleRef.Int32N - select ent); - - Assert.AreEqual(50, int32NullableQuery.AsTableQuery().Execute().Count()); - - // 6. Filter on Date - var dtoQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["DateTimeOffset"].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, dtoQuery.AsTableQuery().Execute().Count()); - - // 7. Filter on Boolean - var boolQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Bool"].BooleanValue == middleRef.Bool - select ent); - - Assert.AreEqual(50, boolQuery.AsTableQuery().Execute().Count()); - - var boolPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["BoolPrimitive"].BooleanValue == middleRef.BoolPrimitive - select ent); - - Assert.AreEqual(50, boolPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 8. Filter on Binary - var binaryQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Binary"].BinaryValue == middleRef.Binary - select ent); - - Assert.AreEqual(1, binaryQuery.AsTableQuery().Execute().Count()); - - var binaryPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["BinaryPrimitive"].BinaryValue == middleRef.BinaryPrimitive - select ent); - - Assert.AreEqual(1, binaryPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 10. Complex Filter on Binary GTE - var complexFilter = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.Properties["String"].StringValue.CompareTo("0050") >= 0 && - ent.Properties["Int64"].Int64Value >= middleRef.Int64 && - ent.Properties["LongPrimitive"].Int64Value >= middleRef.LongPrimitive && - ent.Properties["LongPrimitiveN"].Int64Value >= middleRef.LongPrimitiveN && - ent.Properties["Int32"].Int32Value >= middleRef.Int32 && - ent.Properties["Int32N"].Int32Value >= middleRef.Int32N && - ent.Properties["DateTimeOffset"].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, complexFilter.AsTableQuery().Execute().Count()); - } - #endregion - - #region Negative Tests - - [TestMethod] - [Description("IQueryable - A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithInvalidTakeCount() - { - try - { - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.String.CompareTo("0050") > 0 - select ent).Take(0).ToList(); - - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual("Take count must be positive and greater than 0.", ex.Message); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.String.CompareTo("0050") > 0 - select ent).Take(-1).ToList(); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual("Take count must be positive and greater than 0.", ex.Message); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("IQueryable - A test with invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithInvalidQuery() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.PartitionKey == "tables_batch_2") - select ent); - int count = 0; - foreach (DynamicTableEntity ent in query) - { - count++; - } - Assert.AreEqual(0, count); - } - - [TestMethod] - [Description("IQueryable - multiple from")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableMultipleFrom() - { - TableQuery query = (from ent in currentTable.CreateQuery() - from ent2 in complexEntityTable.CreateQuery() - where ent.RowKey == ent2.RowKey - select ent).AsTableQuery(); - - TestHelper.ExpectedException(() => query.ExecuteSegmented(null), "Multiple from option not allowed in a query"); - } - - [TestMethod] - [Description("IQueryable - validate Reverse")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableReverse() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") > 0) - select ent).Reverse(); - TestHelper.ExpectedException(() => query.Count(), "Reverse option is not supported"); - } - - [TestMethod] - [Description("IQueryable - validate GroupBy")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableGroupBy() - { - var query = (from ent in complexEntityTable.CreateQuery() - group ent.Int32 by ent.Int32 % 5 into mod5Group - select new - { - numbers = mod5Group - }); - - TestHelper.ExpectedException(() => query.Count(), "group by option is not supported"); - } - - [TestMethod] - [Description("IQueryable - validate Distinct")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableDistinct() - { - IQueryable query = (from ent in currentTable.CreateQuery() - select ent.RowKey).Distinct(); - - TestHelper.ExpectedException(() => query.Count(), "Distinct option is not supported"); - } - - [TestMethod] - [Description("IQueryable - validate Set and miscellaneous operators")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableSetOperators() - { - IQueryable query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") >= 0 - select ent.RowKey); - - IQueryable query2 = (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") <= 0 - select ent.RowKey); - // Set operators - TestHelper.ExpectedException(() => query.Union(query2).Count(), "Union is not supported"); - TestHelper.ExpectedException(() => query.Intersect(query2).Count(), "Intersect is not supported"); - TestHelper.ExpectedException(() => query.Except(query2).Count(), "Except is not supported"); - - // Miscellaneous operators - TestHelper.ExpectedException(() => query.Concat(query2).Count(), "Concat is not supported"); - TestHelper.ExpectedException(() => query.SequenceEqual(query2), "SequenceEqual is not supported"); - } - - [TestMethod] - [Description("IQueryable - validate ElementAt")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableElementAt() - { - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") < 0) - select ent).ElementAt(0), "ElementAt is not supported"); - - TestHelper.ExpectedException(() => (from ent in currentTable.CreateQuery() - where (ent.PartitionKey == "tables_batch_1" && ent.RowKey.CompareTo("0050") < 0) - select ent).ElementAtOrDefault(0), "ElementAtOrDefault is not supported"); - } - - [TestMethod] - [Description("IQueryable - validate various aggregation operators")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableAggregation() - { - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") > 0 - select ent.Int32).Sum(), "Sum is not supported"); - - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") > 0 - select ent.Int32).Min(), "Min is not supported"); - - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") > 0 - select ent.Int32).Max(), "Max is not supported"); - - TestHelper.ExpectedException(() => (from ent in complexEntityTable.CreateQuery() - where ent.RowKey.CompareTo("0050") > 0 - select ent.Int32).Average(), "Average is not supported"); - } - - #endregion - - #region Helpers - - private static DynamicTableEntity GenerateRandomEnitity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("test", new EntityProperty("test")); - ent.Properties.Add("a", new EntityProperty("a")); - ent.Properties.Add("b", new EntityProperty("b")); - ent.Properties.Add("c", new EntityProperty("c")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - - internal class POCOEntity : TableEntity - { - public string test { get; set; } - public string a { get; set; } - public string b { get; set; } - public string c { get; set; } - } - - internal class ProjectedPOCO : TableEntity - { - public string test { get; set; } - public string a { get; set; } - public string b { get; set; } - public string c { get; set; } - public string d { get; set; } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableTestBase.cs deleted file mode 100644 index de7c4b85f841f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/Table/TableTestBase.cs +++ /dev/null @@ -1,41 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - public class TableTestBase : TestBase - { - public static string GenerateRandomTableName() - { - return "tbl" + Guid.NewGuid().ToString("N"); - } - - public static string GenerateRandomStringFromCharset(int tableNameLength, string legalChars, Random rand) - { - StringBuilder retString = new StringBuilder(); - for (int n = 0; n < tableNameLength; n++) - { - retString.Append(legalChars[rand.Next(legalChars.Length - 1)]); - } - - return retString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestBase.cs deleted file mode 100644 index bb28b5023c865..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestBase.cs +++ /dev/null @@ -1,55 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Microsoft.WindowsAzure.Storage.Auth; - using System.Xml.Linq; - - [TestClass] - public partial class TestBase - { -#if !WINDOWS_PHONE - [AssemblyInitialize] - public static void AssemblyInitialize(TestContext context) - { - OperationContext.DefaultLogLevel = LogLevel.Off; - } -#endif - - static TestBase() - { - XElement element = XElement.Load(TestConfigurations.DefaultTestConfigFilePath); - TestConfigurations = TestConfigurations.ReadFromXml(element); - - foreach (TenantConfiguration tenant in TestConfigurations.TenantConfigurations) - { - if (tenant.TenantName == TestConfigurations.TargetTenantName) - { - TargetTenantConfig = tenant; - break; - } - } - - StorageCredentials = new StorageCredentials(TargetTenantConfig.AccountName, - TargetTenantConfig.AccountKey); - - CurrentTenantType = TargetTenantConfig.TenantType; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestHelper.cs b/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestHelper.cs deleted file mode 100644 index 0d679d58bb867..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/DotNetCommon/TestHelper.cs +++ /dev/null @@ -1,281 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Fiddler; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Microsoft.WindowsAzure.Test.Network; -using System; -using System.Diagnostics; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestHelper - { - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static void ExpectedException(Action operation, string operationDescription, HttpStatusCode expectedStatusCode, string requestErrorCode = null) - { - try - { - operation(); - } - catch (StorageException ex) - { - Assert.AreEqual((int)expectedStatusCode, ex.RequestInformation.HttpStatusCode, "Http status code is unexpected."); - if (!string.IsNullOrEmpty(requestErrorCode)) - { - Assert.IsNotNull(ex.RequestInformation.ExtendedErrorInformation); - Assert.AreEqual(requestErrorCode, ex.RequestInformation.ExtendedErrorInformation.ErrorCode); - } - return; - } - - Assert.Fail("No exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } - -#if TASK - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static void ExpectedExceptionTask(Task operation, string operationDescription, HttpStatusCode expectedStatusCode, string requestErrorCode = null) - { - try - { - operation.Wait(); - } - catch (AggregateException e) - { - e = e.Flatten(); - if (e.InnerExceptions.Count > 1) - { - Assert.Fail("Multiple exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } - - StorageException ex = e.InnerException as StorageException; - if (ex == null) - { - throw e.InnerException; - } - - Assert.AreEqual((int)expectedStatusCode, ex.RequestInformation.HttpStatusCode, "Http status code is unexpected."); - if (!string.IsNullOrEmpty(requestErrorCode)) - { - Assert.IsNotNull(ex.RequestInformation.ExtendedErrorInformation); - Assert.AreEqual(requestErrorCode, ex.RequestInformation.ExtendedErrorInformation.ErrorCode); - } - return; - } - - Assert.Fail("No exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } -#endif - -#if !WINDOWS_PHONE - internal static void ExecuteAPMMethodWithCancellation(int cancellationDelayInMS, - ProxyBehavior[] behaviors, - Func begin, - Action end) - { - ExecuteAPMMethodWithCancellation(cancellationDelayInMS, - behaviors, - begin, - (res) => - { - end(res); - return true; - }); - } - - internal static void ExecuteAPMMethodWithCancellation(int cancellationDelayInMS, - ProxyBehavior[] behaviors, - Func begin, - Func end) - { - string failMessage = null; - StorageException storageException = null; - OperationContext opContext = new OperationContext(); - - using (HttpMangler proxy = new HttpMangler(false, behaviors)) - { - Debug.WriteLine("Begin"); - using (ManualResetEvent completedEvent = new ManualResetEvent(false)) - { - ICancellableAsyncResult saveResult = begin(null - , opContext, - (resp) => - { - try - { - end(resp); - failMessage = "Request succeeded even after cancellation"; - } - catch (StorageException ex) - { - storageException = ex; - } - catch (Exception badEx) - { - failMessage = badEx.ToString(); - } - finally - { - completedEvent.Set(); - } - }, - null); - - Thread.Sleep(cancellationDelayInMS); - Debug.WriteLine("Cancelling Request"); - saveResult.Cancel(); - - completedEvent.WaitOne(); - TestHelper.AssertNAttempts(opContext, 1); - } - } - - // Do not use IsNull here so that test result contains failMessage - Assert.AreEqual(null, failMessage); - - Assert.IsNotNull(storageException); - Assert.AreEqual("Operation was canceled by user.", storageException.Message); - Assert.AreEqual(306, storageException.RequestInformation.HttpStatusCode); - Assert.AreEqual("Unused", storageException.RequestInformation.HttpStatusMessage); - } - - internal static void ExecuteAPMMethodWithRetry(int ExpectedAttempts, - ProxyBehavior[] behaviors, - Func begin, - Func end) - { - string failMessage = null; - OperationContext opContext = new OperationContext(); - - using (HttpMangler proxy = new HttpMangler(false, behaviors)) - { - Debug.WriteLine("Begin"); - using (ManualResetEvent completedEvent = new ManualResetEvent(false)) - { - ICancellableAsyncResult saveResult = begin(null - , opContext, - (resp) => - { - try - { - Debug.WriteLine("End"); - end(resp); - } - catch (Exception badEx) - { - failMessage = badEx.ToString(); - } - finally - { - completedEvent.Set(); - } - }, - null); - - completedEvent.WaitOne(); - TestHelper.AssertNAttempts(opContext, ExpectedAttempts); - } - } - - // Do not use IsNull here so that test result contains failMessage - Assert.AreEqual(null, failMessage); - } - -#if TASK - internal static void ExecuteTaskMethodWithRetry(int ExpectedAttempts, - ProxyBehavior[] behaviors, - Func> method) - { - OperationContext opContext = new OperationContext(); - - using (HttpMangler proxy = new HttpMangler(false, behaviors)) - { - method(null, opContext).Wait(); - TestHelper.AssertNAttempts(opContext, ExpectedAttempts); - } - } -#endif - - internal static void ExecuteMethodWithRetry(int ExpectedAttempts, - ProxyBehavior[] behaviors, - Func method) - { - OperationContext opContext = new OperationContext(); - - using (HttpMangler proxy = new HttpMangler(false, behaviors)) - { - method(null, opContext); - TestHelper.AssertNAttempts(opContext, ExpectedAttempts); - } - } - - internal static void ExecuteMethodWithRetryInTryFinally(int ExpectedAttempts, - ProxyBehavior[] behaviors, - Func method) - { - OperationContext opContext = new OperationContext(); - - using (HttpMangler proxy = new HttpMangler(false, behaviors)) - { - try - { - method(null, opContext); - } - finally - { - TestHelper.AssertNAttempts(opContext, ExpectedAttempts); - } - } - } - - internal static void VerifyHeaderWasSent(string headerName, string headerValue, Func selector, Action act) - { - string retrievedHeaderValue = null; - using (HttpMangler proxy = new HttpMangler(false, new ProxyBehavior[]{ new ProxyBehavior(session => - { - retrievedHeaderValue = session.oRequest.headers[headerName]; - }, selector, null, TriggerType.BeforeRequest)})) - { - act(); - } - - Assert.AreEqual(headerValue, retrievedHeaderValue); - } -#endif - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet2/README.txt b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet2/README.txt deleted file mode 100644 index 79989e31fb35d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet2/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -Please download FiddlerCore @ http://www.fiddler2.com/Fiddler/Core/ -Please place FiddlerCore.dll here \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet4/README.txt b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet4/README.txt deleted file mode 100644 index fc76ba48aba19..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/DotNet4/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Please download FiddlerCore @ http://www.fiddler2.com/Fiddler/Core/ - -Please place FiddlerCore4.dll here \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/README.txt b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/README.txt deleted file mode 100644 index a29a84aeda2cf..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/Dependencies/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -Please download FiddlerCore @ http://www.fiddler2.com/Fiddler/Core/ - -FiddlerCore.dll needs to be placed in .\DotNet2 -FiddlerCore4.dll needs to be placed in .\DotNet4 \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/BehaviorOptions.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/BehaviorOptions.cs deleted file mode 100644 index 6392e963abeed..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/BehaviorOptions.cs +++ /dev/null @@ -1,100 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// -// The BehaviorOptions class controls how many sessions a behavior will apply to, and for how long it should be applied. -// -//----------------------------------------------------------------------- -namespace Microsoft.WindowsAzure.Test.Network -{ - using System; - using System.Threading; - - /// - /// The BehaviorOptions class controls how many sessions a behavior will apply to, and for how long it should be applied. - /// - public class BehaviorOptions - { - /// - /// The time at which the behavior should expire. - /// - private readonly DateTime expiry; - - /// - /// The number of sessions in which the related behavior has been selected. - /// - private long remainingSessions; - - /// - /// Initializes a new instance of the BehaviorOptions class. - /// - public BehaviorOptions() - : this(expiry: DateTime.MaxValue) - { - } - - /// - /// Initializes a new instance of the BehaviorOptions class with a specified number - /// of sessions to which the behavior should be applied. - /// - /// The number of sessions to apply this behavior to. - public BehaviorOptions(long maximumRemainingSessions) - : this(expiry: DateTime.MaxValue, maximumRemainingSessions: maximumRemainingSessions) - { - } - - /// - /// Initializes a new instance of the BehaviorOptions class with with an expiry time and - /// a maximum number of sessions to which the behavior should be applied. - /// - /// The time at which the behavior should no longer be applied. - /// The maximum number of sessions the behavior should be applied. - public BehaviorOptions(DateTime expiry, long maximumRemainingSessions = long.MaxValue) - { - this.remainingSessions = maximumRemainingSessions; - this.expiry = expiry; - } - - /// - /// Gets the DateTime at which this behavior should no longer be applied. - /// - public DateTime Expiry - { - get { return this.expiry; } - } - - /// - /// Gets the number of sessions before this behavior will no longer be applied. - /// - public long RemainingSessions - { - get { return this.remainingSessions; } - } - - /// - /// DecrementSessionCount notes that this behavior has been applied. - /// - public void DecrementSessionCount() - { - Interlocked.Decrement(ref this.remainingSessions); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/BufferBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/BufferBehaviors.cs deleted file mode 100644 index c0f1a3b3a4e67..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/BufferBehaviors.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - /// - /// BufferBehaviors describes behaviors that affect the buffering of responses before they're returned to the calling code. - /// - public static class BufferBehaviors - { - /// - /// BufferRequests returns a behavior that ensures the responses from the server are fully buffered - /// before they're delivered to user code. - /// - /// The relevant behavior. - public static ProxyBehavior BufferResponses() - { - return new ProxyBehavior(session => session.bBufferResponse = true, type: TriggerType.BeforeRequest); - } - - /// - /// BufferRequests returns a behavior that ensures the responses from the server are not buffered. - /// - /// The relevant behavior. - public static ProxyBehavior DoNotBufferResponses() - { - return new ProxyBehavior(session => session.bBufferResponse = false, type: TriggerType.BeforeRequest); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayBehaviors.cs deleted file mode 100644 index 70a629e79d0b3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayBehaviors.cs +++ /dev/null @@ -1,245 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - using Fiddler; - using System; - - /// - /// DelayBehaviors control whether the sessions should be delayed before being delivered to user code. - /// - public static class DelayBehaviors - { - /// - /// DelayAllRequests returns a behavior that delays all requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior DelayAllRequests(int delayInMs, BehaviorOptions options = null) - { - return new DelayRequestBehavior(delayInMs, null, options); - } - - /// - /// DelayAllRequestsIf returns a behavior that delays requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The predicate controlling when to delay the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior DelayAllRequestsIf(int delayInMs, Func selector, BehaviorOptions options = null) - { - return new DelayRequestBehavior(delayInMs, selector, options); - } - - /// - /// DelayAllRequestsUntil returns a behavior that delays all requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The DateTime at which to stop delaying requests. - /// The relevant behavior. - public static ProxyBehavior DelayAllRequestsUntil(int delayInMs, DateTime expiry) - { - return new DelayRequestBehavior(delayInMs, expiry); - } - - /// - /// DelayAllRequestsUntilIf returns a behavior that delays all requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The DateTime at which to stop delaying requests. - /// The predicate controlling when to delay the request. - /// The relevant behavior. - public static ProxyBehavior DelayAllRequestsUntilIf(int delayInMs, DateTime expiry, Func selector) - { - return new DelayRequestBehavior(delayInMs, expiry, selector); - } - - /// - /// DelayNRequests returns a behavior that delays requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The maximum number of sessions which should be delayed. - /// The relevant behavior. - public static ProxyBehavior DelayNRequests(int delayInMs, int n) - { - return new DelayRequestBehavior(delayInMs, n); - } - - /// - /// DelayNRequestsIf returns a behavior that delays requests the specified number of milliseconds. - /// - /// The time in milliseconds to delay the request. - /// The maximum number of sessions which should be delayed. - /// The predicate controlling when to delay the request. - /// The relevant behavior. - public static ProxyBehavior DelayNRequestsIf(int delayInMs, int n, Func selector) - { - return new DelayRequestBehavior(delayInMs, n, selector); - } - - /// - /// DelayAllResponses returns a behavior that delays all responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior DelayAllResponses(int delayInMs, BehaviorOptions options = null) - { - return new DelayResponseBehavior(delayInMs, null, options); - } - - /// - /// DelayAllResponsesIf returns a behavior that delays responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The predicate controlling when to delay the response. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior DelayAllResponsesIf(int delayInMs, Func selector, BehaviorOptions options = null) - { - return new DelayResponseBehavior(delayInMs, selector, options); - } - - /// - /// DelayAllResponsesUntil returns a behavior that delays responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The DateTime at which to stop delaying responses. - /// The relevant behavior. - public static ProxyBehavior DelayAllResponsesUntil(int delayInMs, DateTime expiry) - { - return new DelayResponseBehavior(delayInMs, expiry); - } - - /// - /// DelayAllResponsesUntilIf returns a behavior that delays responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The DateTime at which to stop delaying responses. - /// The predicate controlling when to delay the response. - /// The relevant behavior. - public static ProxyBehavior DelayAllResponsesUntilIf(int delayInMs, DateTime expiry, Func selector) - { - return new DelayResponseBehavior(delayInMs, expiry, selector); - } - - /// - /// DelayNResponses returns a behavior that delays responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The maximum number of sessions which should be delayed. - /// The relevant behavior. - public static ProxyBehavior DelayNResponses(int delayInMs, int n) - { - return new DelayResponseBehavior(delayInMs, n); - } - - /// - /// DelayNResponsesIf returns a behavior that delays responses the specified number of milliseconds. - /// - /// The time in milliseconds to delay the response. - /// The maximum number of sessions which should be delayed. - /// The predicate controlling when to delay the response. - /// The relevant behavior. - public static ProxyBehavior DelayNResponsesIf(int delayInMs, int n, Func selector) - { - return new DelayResponseBehavior(delayInMs, n, selector); - } - - /// - /// Helper class for request (outgoing) delays. - /// - private class DelayRequestBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the DelayRequestBehavior class. - /// - /// The time in milliseconds to delay the request. - /// The predicate controlling when to delay the request. - /// The options controlling the behavior. - public DelayRequestBehavior(int delayInMs, Func selector = null, BehaviorOptions options = null) - : base(session => session.oRequest.pipeClient.TransmitDelay = delayInMs, selector, options, TriggerType.BeforeRequest) - { - } - - /// - /// Initializes a new instance of the DelayRequestBehavior class. - /// - /// The time in milliseconds to delay the request. - /// The maximum number of sessions which should be delayed. - /// The predicate controlling when to delay the request. - public DelayRequestBehavior(int delayInMs, int n, Func selector = null) - : this(delayInMs, selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the DelayRequestBehavior class. - /// - /// The time in milliseconds to delay the request. - /// The DateTime at which to no longer delay requests. - /// The predicate controlling when to delay the request. - public DelayRequestBehavior(int delayInMs, DateTime expiry, Func selector = null) - : this(delayInMs, selector, new BehaviorOptions(expiry)) - { - } - } - - /// - /// Helper class for response (incoming) delays. - /// - private class DelayResponseBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the DelayResponseBehavior class. - /// - /// The time in milliseconds to delay the response. - /// The predicate controlling when to delay the response. - /// The options controlling the behavior. - public DelayResponseBehavior(int delayInMs, Func selector = null, BehaviorOptions options = null) - : base(session => session.oResponse.pipeServer.TransmitDelay = delayInMs, selector, options, TriggerType.BeforeResponse) - { - } - - /// - /// Initializes a new instance of the DelayResponseBehavior class. - /// - /// The time in milliseconds to delay the response. - /// The maximum number of sessions which should be delayed. - /// The predicate controlling when to delay the response. - public DelayResponseBehavior(int delayInMs, int n, Func selector = null) - : this(delayInMs, selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the DelayResponseBehavior class. - /// - /// The time in milliseconds to delay the response. - /// The DateTime at which to no longer delay responses. - /// The predicate controlling when to delay the response. - public DelayResponseBehavior(int delayInMs, DateTime expiry, Func selector = null) - : this(delayInMs, selector, new BehaviorOptions(expiry)) - { - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayedActionBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayedActionBehaviors.cs deleted file mode 100644 index 322ddd492dc82..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/DelayedActionBehaviors.cs +++ /dev/null @@ -1,133 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Fiddler; -using System; -using System.Timers; - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - /// - /// Factory for Behaviours to execute an action based on a time or network based delay - /// - public static class DelayedActionBehaviors - { - /// - /// AbortSession returns an action which Aborts a Session - /// - /// The relevant action. - public static Action AbortSession() - { - return session => session.Abort(); - } - - /// - /// EndSessionWithTCPReset returns an action which ends a session by sending a tcp reset. - /// - /// The relevant action. - public static Action EndSessionWithTCPReset() - { - return session => session.oRequest.pipeClient.EndWithRST(); - } - - /// - /// Executes a given action after a given number of ms. - /// - /// The action to execute. - /// The delay in MS. - /// The predicate controlling when to tamper with the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior ExecuteAfter(Action action, int delayInMs, Func selector, BehaviorOptions options = null) - { - return new DelayedActionBehavior(action, delayInMs, null, selector, options); - } - - /// - /// Aborts an Session after a given number of ms. - /// - /// The delay in MS. - /// The predicate controlling when to tamper with the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior AbortRequestAfter(int delayInMs, Func selector, BehaviorOptions options = null) - { - return ExecuteAfter(AbortSession(), delayInMs, selector, options); - } - - /// - /// Sends a TCP reset after a given number of ms. - /// - /// The delay in MS. - /// The predicate controlling when to tamper with the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior SendTCPResetAfter(int delayInMs, Func selector, BehaviorOptions options = null) - { - return ExecuteAfter(EndSessionWithTCPReset(), delayInMs, selector, options); - } - - /// - /// Helper class for DelayedActions - /// - private class DelayedActionBehavior : ProxyBehavior - { - private const int POLLING_INTERVAL = 100; - - /// - /// Initializes a new instance of the DelayedActionBehavior class. - /// - /// The Action to execute after the delay - /// The time in milliseconds to delay the request. - /// The interval in ms to poll. For single backoff delays this is the backoff in ms. - /// The predicate controlling when to delay the request. - /// The options controlling the behavior. - public DelayedActionBehavior(Action action, int? delayInMs, Func pollingSelector = null, Func selector = null, BehaviorOptions options = null) - : base((session) => DelayAction(session, action, delayInMs, pollingSelector), selector, options, TriggerType.BeforeRequest) - { - } - - private static void DelayAction(Session inSession, Action action, int? pollingInterval, Func pollingSelector) - { - pollingSelector = pollingSelector ?? Selectors.Always(); - pollingInterval = pollingInterval ?? POLLING_INTERVAL; - - Timer delayTimer = new Timer() - { - AutoReset = false, - Interval = pollingInterval.Value - }; - - delayTimer.Elapsed += (sender, obj) => - { - if (pollingSelector(inSession)) - { - delayTimer.Stop(); - delayTimer.Dispose(); - action(inSession); - } - else - { - delayTimer.Start(); - } - }; - - delayTimer.Start(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/IgnoreBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/IgnoreBehaviors.cs deleted file mode 100644 index 549ddf52fdf84..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/IgnoreBehaviors.cs +++ /dev/null @@ -1,245 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - using Fiddler; - using System; - - /// - /// IgnoreBehaviors contains a set of behaviors which allow sessions to be ignored. - /// - public static class IgnoreBehaviors - { - /// - /// IgnoreAllRequests returns a behavior ignoring all requests. - /// - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllRequests(BehaviorOptions options = null) - { - return new IgnoreRequestBehavior(null, options); - } - - /// - /// IgnoreAllRequestsIf returns a behavior ignoring requests which meet some criterion. - /// - /// The predicate controlling when to ignore the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllRequestsIf(Func selector, BehaviorOptions options = null) - { - return new IgnoreRequestBehavior(selector, options); - } - - /// - /// IgnoreAllRequestsUntil returns a behavior ignoring requests until some DateTime is reached. - /// - /// The DateTime at which to stop ignoring requests. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllRequestsUntil(DateTime expiry) - { - return new IgnoreRequestBehavior(expiry); - } - - /// - /// IgnoreAllRequestsUntilIf returns a behavior ignoring requests until some DateTime is reached. - /// - /// The DateTime at which to stop ignoring requests. - /// The predicate controlling when to ignore the request. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllRequestsUntilIf(DateTime expiry, Func selector) - { - return new IgnoreRequestBehavior(expiry, selector); - } - - /// - /// IgnoreNRequests returns a behavior ignoring requests until some maximum session count is reached. - /// - /// The maximum number of sessions which should be ignored. - /// The relevant behavior. - public static ProxyBehavior IgnoreNRequests(int n) - { - return new IgnoreRequestBehavior(n); - } - - /// - /// IgnoreNRequestsIf returns a behavior ignoring requests until some maximum session count is reached. - /// - /// The maximum number of sessions which should be ignored. - /// The predicate controlling when to ignore the request. - /// The relevant behavior. - public static ProxyBehavior IgnoreNRequestsIf(int n, Func selector) - { - return new IgnoreRequestBehavior(n, selector); - } - - /// - /// IgnoreAllResponses returns a behavior which ignores all responses. - /// - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllResponses(BehaviorOptions options = null) - { - return new IgnoreResponseBehavior(null, options); - } - - /// - /// IgnoreAllResponsesIf returns a behavior which ignores responses which meet some criterion. - /// - /// The predicate controlling when to ignore the response. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllResponsesIf(Func selector, BehaviorOptions options = null) - { - return new IgnoreResponseBehavior(selector, options); - } - - /// - /// IgnoreAllResponsesUntil returns a behavior which ignores responses until some DateTime is reached. - /// - /// The DateTime at which to stop ignoring responses. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllResponsesUntil(DateTime expiry) - { - return new IgnoreResponseBehavior(expiry); - } - - /// - /// IgnoreAllResponsesUntilIf returns a behavior which ignores responses until some DateTime is reached. - /// - /// The DateTime at which to stop ignoring responses. - /// The predicate controlling when to ignore the response. - /// The relevant behavior. - public static ProxyBehavior IgnoreAllResponsesUntilIf(DateTime expiry, Func selector) - { - return new IgnoreResponseBehavior(expiry, selector); - } - - /// - /// IgnoreNResponses returns a behavior which ignores responses until some maximum session count is reached. - /// - /// The maximum number of sessions to ignore. - /// The relevant behavior. - public static ProxyBehavior IgnoreNResponses(int n) - { - return new IgnoreResponseBehavior(n); - } - - /// - /// IgnoreNResponsesIf returns a behavior which ignores responses until some maximum session count is reached. - /// - /// The maximum number of sessions to ignore. - /// The predicate controlling when to ignore the response. - /// The relevant behavior. - public static ProxyBehavior IgnoreNResponsesIf(int n, Func selector) - { - return new IgnoreResponseBehavior(n, selector); - } - - /// - /// IgnoreRequest ignores the outgoing request. - /// - /// The session whose request should be failed. - private static void IgnoreRequest(Session relevantSession) - { - relevantSession["x-breakrequest"] = "breaking for abort"; - relevantSession.Abort(); - } - - /// - /// IgnoreResponse ignores the incoming response. - /// - /// The session whose response should be failed. - private static void IgnoreResponse(Session relevantSession) - { - relevantSession.LoadResponseFromFile(StockResponses.NoContent204); - } - - /// - /// IgnoreRequestBehavior is a helper class for ignoring requests (outgoing). - /// - private class IgnoreRequestBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the IgnoreRequestBehavior class. - /// - /// The predicate controlling when to ignore the request. - /// The options controlling the behavior. - public IgnoreRequestBehavior(Func selector = null, BehaviorOptions options = null) - : base(IgnoreRequest, selector, options, TriggerType.BeforeRequest) - { - } - - /// - /// Initializes a new instance of the IgnoreRequestBehavior class. - /// - /// The maximum number of sessions to ignore. - /// The predicate controlling when to ignore the request. - public IgnoreRequestBehavior(int n, Func selector = null) - : this(selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the IgnoreRequestBehavior class. - /// - /// The DateTime at which to stop ignoring requests. - /// The predicate controlling when to ignore the request. - public IgnoreRequestBehavior(DateTime expiry, Func selector = null) - : this(selector, new BehaviorOptions(expiry)) - { - } - } - - /// - /// IgnoreResponseBehavior is a helper class for ignoring responses (incoming). - /// - private class IgnoreResponseBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the IgnoreResponseBehavior class. - /// - /// The predicate controlling when to ignore the response. - /// The options controlling the behavior. - public IgnoreResponseBehavior(Func selector = null, BehaviorOptions options = null) - : base(IgnoreResponse, selector, options, TriggerType.BeforeResponse) - { - } - - /// - /// Initializes a new instance of the IgnoreResponseBehavior class. - /// - /// The maximum number of sessions to ignore. - /// The predicate controlling when to ignore the response. - public IgnoreResponseBehavior(int n, Func selector = null) - : this(selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the IgnoreResponseBehavior class. - /// - /// The DateTime at which to stop ignoring responses. - /// The predicate controlling when to ignore the response. - public IgnoreResponseBehavior(DateTime expiry, Func selector = null) - : this(selector, new BehaviorOptions(expiry)) - { - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/PerformanceBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/PerformanceBehaviors.cs deleted file mode 100644 index aa47e7476bd26..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/PerformanceBehaviors.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - using Fiddler; - using System; - - /// - /// PerformanceBehaviors both measure and influence the performance of the sessions to which they are applied. - /// - public static class PerformanceBehaviors - { - /// - /// InsertUpstreamNetworkDelay inserts a delay per KB uploaded. - /// - /// How much time, in milliseconds, to delay each KB. - /// The predicate controlling when to insert upstream network delay. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior InsertUpstreamNetworkDelay(int delayInMs, Func selector = null, BehaviorOptions options = null) - { - return new ProxyBehavior(session => session["request-trickle-delay"] = Convert.ToString(delayInMs), selector, options, TriggerType.BeforeRequest); - } - - /// - /// InsertDownstreamNetworkDelay inserts a delay per KB downloaded. - /// - /// How much time, in milliseconds, to delay each KB. - /// The predicate controlling when to insert downstream network delay. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior InsertDownstreamNetworkDelay(int delayInMs, Func selector = null, BehaviorOptions options = null) - { - return new ProxyBehavior(session => session["response-trickle-delay"] = Convert.ToString(delayInMs), selector, options, TriggerType.BeforeResponse); - } - - /// - /// LogSessionPerfData raises an event when the perf counter for the session is available. - /// - /// The action to perform when the session timers are available. - /// The predicate controlling when to log performance data. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior LogSessionPerfData(Action onTimerAvailablity, Func selector = null, BehaviorOptions options = null) - { - return new ProxyBehavior(session => onTimerAvailablity(session, session.Timers), selector, options, TriggerType.AfterSessionComplete); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/TamperBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/TamperBehaviors.cs deleted file mode 100644 index 9d5332ab67c2f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Behaviors/TamperBehaviors.cs +++ /dev/null @@ -1,288 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network.Behaviors -{ - using Fiddler; - using System; - - /// - /// TamperBehaviors modify the outgoing (request) and incoming (response) data streams. - /// - public class TamperBehaviors - { - /// - /// AddHeaderToRequest returns an action which adds an HTTP header to a request. - /// - /// The name of the header to be added. - /// The value of the header to be added. - /// The relevant action. - public static Action AddHeaderToRequest(string headerName, string headerValue) - { - return session => session.oRequest[headerName] = headerValue; - } - - /// - /// DeleteHeaderFromRequest removes the given header from the request. - /// - /// The name of the header to remove. - /// The relevant action. - public static Action DeleteHeaderFromRequest(string headerName) - { - return session => session.oRequest.headers.Remove(headerName); - } - - /// - /// AddHeaderToResponse returns an action which adds an HTTP header to a response. - /// - /// The name of the header to be added. - /// The value of the header to be added. - /// The relevant action. - public static Action AddHeaderToResponse(string headerName, string headerValue) - { - return session => session.oResponse[headerName] = headerValue; - } - - /// - /// DeleteHeaderFromResponse removes the given header from the response. - /// - /// The name of the header to remove. - /// The relevant action. - public static Action DeleteHeaderFromResponse(string headerName) - { - return session => session.oResponse.headers.Remove(headerName); - } - - /// - /// TamperAllRequests returns a behavior which tampers with all requests. - /// - /// An action specifying how to tamper with the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior TamperAllRequests(Action tamperAction, BehaviorOptions options = null) - { - return new TamperRequestBehavior(tamperAction, null, options); - } - - /// - /// TamperAllRequestsIf returns a behavior which tampers with all requests which meet a specified criterion. - /// - /// An action specifying how to tamper with the request. - /// The predicate controlling when to tamper with the request. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior TamperAllRequestsIf(Action tamperAction, Func selector, BehaviorOptions options = null) - { - return new TamperRequestBehavior(tamperAction, selector, options); - } - - /// - /// TamperRequestsUntil returns a behavior which tampers with all requests until a certain time. - /// - /// An action specifying how to tamper with the request. - /// The DateTime at which to stop tampering with requests. - /// The relevant behavior. - public static ProxyBehavior TamperRequestsUntil(Action tamperAction, DateTime expiry) - { - return new TamperRequestBehavior(tamperAction, expiry); - } - - /// - /// TamperRequestsUntilIf returns a behavior which tampers with requests until a certain time. - /// - /// An action specifying how to tamper with the request. - /// The DateTime at which to stop tampering with requests. - /// The predicate controlling when to tamper with the request. - /// The relevant behavior. - public static ProxyBehavior TamperRequestsUntilIf(Action tamperAction, DateTime expiry, Func selector) - { - return new TamperRequestBehavior(tamperAction, expiry, selector); - } - - /// - /// TamperNRequests returns a behavior which tampers with all requests until some maximum session count is reached. - /// - /// An action specifying how to tamper with the request. - /// The maximum number of sessions to tamper. - /// The relevant behavior. - public static ProxyBehavior TamperNRequests(Action tamperAction, int n) - { - return new TamperRequestBehavior(tamperAction, n); - } - - /// - /// TamperNRequestsIf returns a behavior which tampers with all requests until some maximum session count is reached. - /// - /// An action specifying how to tamper with the request. - /// The maximum number of sessions to tamper. - /// The predicate controlling when to tamper with the request. - /// The relevant behavior. - public static ProxyBehavior TamperNRequestsIf(Action tamperAction, int n, Func selector) - { - return new TamperRequestBehavior(tamperAction, n, selector); - } - - /// - /// TamperAllResponses returns a behavior which tampers with all responses. - /// - /// An action specifying how to tamper with the response. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior TamperAllResponses(Action tamperAction, BehaviorOptions options = null) - { - return new TamperResponseBehavior(tamperAction, null, options); - } - - /// - /// TamperAllResponsesIf returns a behavior which tampers with responses meeting the given criterion. - /// - /// An action specifying how to tamper with the response. - /// The predicate controlling when to tamper with the response. - /// The options controlling the behavior. - /// The relevant behavior. - public static ProxyBehavior TamperAllResponsesIf(Action tamperAction, Func selector, BehaviorOptions options = null) - { - return new TamperResponseBehavior(tamperAction, selector, options); - } - - /// - /// TamperResponsesUntil returns a behavior which tampers with responses until a certain DateTime is reached. - /// - /// An action specifying how to tamper with the response. - /// The DateTime at which to stop tampering with responses. - /// The relevant behavior. - public static ProxyBehavior TamperResponsesUntil(Action tamperAction, DateTime expiry) - { - return new TamperResponseBehavior(tamperAction, expiry); - } - - /// - /// TamperResponsesUntilIf returns a behavior which tampers with responses meeting the given criterion, - /// until a certain DateTime is reached. - /// - /// An action specifying how to tamper with the response. - /// The DateTime at which to stop tampering with responses. - /// The predicate controlling when to tamper with the response. - /// The relevant behavior. - public static ProxyBehavior TamperResponsesUntilIf(Action tamperAction, DateTime expiry, Func selector) - { - return new TamperResponseBehavior(tamperAction, expiry, selector); - } - - /// - /// TamperNResponsesIf returns a behavior which tampers with all until a maximum session count is reached. - /// - /// An action specifying how to tamper with the response. - /// The maximum number of sessions with which to tamper. - /// The relevant behavior. - public static ProxyBehavior TamperNResponses(Action tamperAction, int n) - { - return new TamperResponseBehavior(tamperAction, n); - } - - /// - /// TamperNResponsesIf returns a behavior which tampers with responses meeting the given criterion, - /// until a maximum session count is reached. - /// - /// An action specifying how to tamper with the response. - /// The maximum number of sessions with which to tamper. - /// The predicate controlling when to tamper with the response. - /// The relevant behavior. - public static ProxyBehavior TamperNResponsesIf(Action tamperAction, int n, Func selector) - { - return new TamperResponseBehavior(tamperAction, n, selector); - } - - /// - /// Helper class for request (outgoing) tampering. - /// - private class TamperRequestBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the TamperRequestBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The predicate controlling when to tamper with the request. - /// The options controlling the behavior. - public TamperRequestBehavior(Action tamperAction, Func selector = null, BehaviorOptions options = null) - : base(tamperAction, selector, options, TriggerType.BeforeRequest) - { - } - - /// - /// Initializes a new instance of the TamperRequestBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The maximum number of sessions which should be tampered with. - /// The predicate controlling when to tamper with the request. - public TamperRequestBehavior(Action tamperAction, int n, Func selector = null) - : this(tamperAction, selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the TamperRequestBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The DateTime at which to no longer tamper with requests. - /// The predicate controlling when to tamper with the request. - public TamperRequestBehavior(Action tamperAction, DateTime expiry, Func selector = null) - : this(tamperAction, selector, new BehaviorOptions(expiry)) - { - } - } - - /// - /// Helper class for response (incoming) tampering. - /// - private class TamperResponseBehavior : ProxyBehavior - { - /// - /// Initializes a new instance of the TamperResponseBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The predicate controlling when to tamper with the response. - /// The options controlling the behavior. - public TamperResponseBehavior(Action tamperAction, Func selector = null, BehaviorOptions options = null) - : base(tamperAction, selector, options, TriggerType.BeforeResponse) - { - } - - /// - /// Initializes a new instance of the TamperResponseBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The maximum number of sessions which should be tampered with. - /// The predicate controlling when to tamper with the response. - public TamperResponseBehavior(Action tamperAction, int n, Func selector = null) - : this(tamperAction, selector, new BehaviorOptions(maximumRemainingSessions: n)) - { - } - - /// - /// Initializes a new instance of the TamperResponseBehavior class. - /// - /// An action specifying how to tamper with the response. - /// The DateTime at which to no longer tamper with responses. - /// The predicate controlling when to tamper with the response. - public TamperResponseBehavior(Action tamperAction, DateTime expiry, Func selector = null) - : this(tamperAction, selector, new BehaviorOptions(expiry)) - { - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.cs deleted file mode 100644 index 770ccb72c5397..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.cs +++ /dev/null @@ -1,317 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network -{ - using Fiddler; - using System; - using System.Net; - using System.Threading; - - /// - /// HttpMangler is a test utility for mucking with the either the request to or the response from an HTTP server. - /// - public class HttpMangler : IDisposable - { - /// - /// We'll use a global static to run the Fiddler initialization code, and trust that - /// the finalizer call will run at normal process exit. - /// - private static readonly FiddlerOneTimeInitializer initializeFiddlerAndGlobalProxySettings = new FiddlerOneTimeInitializer(); - - /// - /// Gets or sets a value indicating whether the default proxy is the mangler proxy or not. - /// - public static bool Active - { - get - { - return WebRequest.DefaultWebProxy == HttpMangler.initializeFiddlerAndGlobalProxySettings.NewProxy; - } - - set - { - if (value) - { - WebRequest.DefaultWebProxy = HttpMangler.initializeFiddlerAndGlobalProxySettings.NewProxy; - } - else - { - WebRequest.DefaultWebProxy = HttpMangler.initializeFiddlerAndGlobalProxySettings.OldProxy; - } - } - } - - /// - /// The behaviors this instance of HttpMangler is tracking - /// - private readonly ProxyBehavior[] behaviors; - - private bool drainSessions; - - private int outstandingEvents = 0; - - private bool shuttingDown = false; - - /// - /// How many sessions are there? - /// - private int sessionCount; - - /// - /// Whether this object has been torn down or not. - /// - private bool disposed = false; - - /// - /// Initializes a new instance of the HttpMangler class with the given set of behaviors - /// - /// The behaviors to use while this class is alive - public HttpMangler(params ProxyBehavior[] behaviors) - : this(true, behaviors) - { - } - - /// - /// Initializes a new instance of the HttpMangler class with the given set of behaviors - /// - /// Determines if all sessions are allowed to complete on shutdown - /// The behaviors to use while this class is alive - public HttpMangler(bool drainEventsOnShutdown, ProxyBehavior[] behaviors) - { - HttpMangler.Active = true; - - this.sessionCount = 0; - this.behaviors = behaviors; - this.drainSessions = drainEventsOnShutdown; - - FiddlerApplication.BeforeRequest += this.FiddlerApplication_BeforeRequest; - FiddlerApplication.BeforeResponse += this.FiddlerApplication_BeforeResponse; - FiddlerApplication.BeforeReturningError += this.FiddlerApplication_BeforeReturningError; - FiddlerApplication.AfterSessionComplete += this.FiddlerApplication_AfterSessionComplete; - FiddlerApplication.ResponseHeadersAvailable += this.FiddlerApplication_ResponseHeadersAvailable; - } - - /// - /// Finalizes an instance of the HttpMangler class, unhooking it from all events. - /// - ~HttpMangler() - { - this.Dispose(false); - } - - /// - /// Gets how many sessions this mangler has seen. - /// - public int Sessions - { - get { return this.sessionCount; } - } - - /// - /// Cleans up the HttpMangler instance, blocking until all events have been seen. - /// - public void Dispose() - { - this.Dispose(true); - } - - /// - /// Dispose cleans up all unused resources of the HttpMangler class. - /// - /// Whether being called by a finalizer (false) or Dispose method (true) - private void Dispose(bool disposing) - { - if (!this.disposed) - { - shuttingDown = true; - - FiddlerApplication.BeforeRequest -= this.FiddlerApplication_BeforeRequest; - FiddlerApplication.BeforeResponse -= this.FiddlerApplication_BeforeResponse; - FiddlerApplication.BeforeReturningError -= this.FiddlerApplication_BeforeReturningError; - FiddlerApplication.ResponseHeadersAvailable -= this.FiddlerApplication_ResponseHeadersAvailable; - - // Wait for all items to finish - drainOutStandingRequests(TimeSpan.FromMinutes(1)); - - FiddlerApplication.AfterSessionComplete -= this.FiddlerApplication_AfterSessionComplete; - - HttpMangler.Active = false; - this.disposed = true; - - if (disposing) - { - GC.SuppressFinalize(this); - } - } - } - - private void drainOutStandingRequests(TimeSpan timeout) - { - DateTime expiry = DateTime.Now + timeout; - - while (this.drainSessions && outstandingEvents > 0 && DateTime.Now < expiry) - { - Thread.Sleep(Math.Max(0, Math.Min(100, (int)(expiry - DateTime.Now).TotalMilliseconds))); - } - } - - /// - /// HandleFiddlerEvent deals with all events from Fiddler - /// - /// The relevant session for this event - /// An enum value representing the type of event that has been raised - private void HandleFiddlerEvent(Session openSession, TriggerType triggerFlag) - { - for (int i = 0; i < this.behaviors.Length; ++i) - { - if (this.ShouldCallBehavior(this.behaviors[i], openSession, triggerFlag)) - { - this.behaviors[i].Execute(openSession); - } - } - } - - /// - /// ShouldCallBehavior handles all logic about whether a behavior should be invoked on a session. - /// - /// The relevant behavior - /// The relevant session - /// The type of event - /// True if the behavior should be invoked on this session; false otherwise - private bool ShouldCallBehavior(ProxyBehavior proxyBehavior, Session openSession, TriggerType triggerFlag) - { - return TriggerType.None != (proxyBehavior.TriggerFlags & triggerFlag) - && DateTime.Now < proxyBehavior.Options.Expiry - && 0 < proxyBehavior.Options.RemainingSessions - && proxyBehavior.Selector(openSession); - } - - /// - /// FiddlerApplication_BeforeRequest is invoked before the HTTP call goes out to the remote server. - /// - /// The relevant session - private void FiddlerApplication_BeforeRequest(Session openSession) - { - // If we're shutting down, don't do any more work - if (shuttingDown) - { - return; - } - - this.sessionCount += 1; - - // On the first iteration, the wait will be signaled and we can't increment -- so, reset to 1 - Interlocked.Increment(ref outstandingEvents); - - this.HandleFiddlerEvent(openSession, TriggerType.BeforeRequest); - } - - /// - /// FiddlerApplication_BeforeReturningError is invoked when an error response is generated by Fiddler. - /// - /// The relevant session. - private void FiddlerApplication_BeforeReturningError(Session openSession) - { - this.HandleFiddlerEvent(openSession, TriggerType.BeforeReturningError); - } - - /// - /// FiddlerApplication_AfterSessionComplete is invoked when a session has been completed. - /// - /// The relevant session. - private void FiddlerApplication_AfterSessionComplete(Session openSession) - { - this.HandleFiddlerEvent(openSession, TriggerType.AfterSessionComplete); - Interlocked.Decrement(ref outstandingEvents); - } - - /// - /// FiddlerApplication_BeforeResponse is invoked when a server response is received by Fiddler. - /// - /// The relevant session. - private void FiddlerApplication_BeforeResponse(Session openSession) - { - this.HandleFiddlerEvent(openSession, TriggerType.BeforeResponse); - } - - /// - /// FiddlerApplication_ResponseHeadersAvailable is invoked when Response Headers are available. - /// - /// The relevant session. - private void FiddlerApplication_ResponseHeadersAvailable(Session openSession) - { - this.HandleFiddlerEvent(openSession, TriggerType.ResponseHeadersAvailable); - } - - /// - /// FiddlerOneTimeInitializer initializes Fiddler on port 8877 for the current process only, - /// setting the default web proxy to go through it. This class is intended to be stored in a - /// private static readonly variable, so that it only is invoked once in an AppDomain's lifetime. - /// - private class FiddlerOneTimeInitializer - { - private readonly IWebProxy oldProxy; - private readonly IWebProxy newProxy; - - /// - /// Gets the old default proxy prior to setting it in constructor. - /// - public IWebProxy OldProxy - { - get { return this.oldProxy; } - } - - /// - /// Gets the new default proxy after setting it in constructor. - /// - public IWebProxy NewProxy - { - get { return this.newProxy; } - } - - /// - /// Initializes a new instance of the FiddlerOneTimeInitializer class. - /// - public FiddlerOneTimeInitializer() - { - FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true); - - // We'd like all default values, but we don't want to muck with system settings or - // SSL connections. - FiddlerCoreStartupFlags flags = FiddlerCoreStartupFlags.Default - & ~FiddlerCoreStartupFlags.RegisterAsSystemProxy - & ~FiddlerCoreStartupFlags.DecryptSSL; - - // For now, hardcoding 8877 for the proxy port seems appropriate. - FiddlerApplication.Startup(8877, flags); - - this.oldProxy = WebRequest.DefaultWebProxy; - this.newProxy = new WebProxy("http://localhost:8877", true); - } - - /// - /// Finalizes an instance of the FiddlerOneTimeInitializer class, causing the Fiddler proxy to shut down. - /// - ~FiddlerOneTimeInitializer() - { - FiddlerApplication.Shutdown(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.csproj b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.csproj deleted file mode 100644 index d815911d04ae6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/HttpMangler.csproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {CA607E8F-2906-4065-A1A9-4A3733F0CC31} - Library - Properties - Microsoft.WindowsAzure.Test.Network - HttpMangler - v4.0 - 512 - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - $(OutputPath)\$(AssemblyName).xml - true - 1685 - - - pdbonly - true - bin\Release\ - prompt - 4 - $(OutputPath)\$(AssemblyName).xml - true - TRACE - 1685 - - - - ..\Dependencies\DotNet2\FiddlerCore.dll - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Properties/AssemblyInfo.cs deleted file mode 100644 index 976929a3e1aae..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,43 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// -// Version information for this assembly (for VS only.) -// -//----------------------------------------------------------------------- -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestProxy")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("TestProxy")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("823a0253-7437-45a6-b991-224028c005be")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ProxyBehavior.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ProxyBehavior.cs deleted file mode 100644 index d5718e2dc57cc..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ProxyBehavior.cs +++ /dev/null @@ -1,107 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network -{ - using Fiddler; - using System; - - /// - /// The ProxyBehavior class controls how the HttpMangler processes the incoming and outgoing network data. - /// - public class ProxyBehavior - { - /// - /// Holds the options for this behavior - /// - private readonly BehaviorOptions options; - - /// - /// Holds the predicate controlling the conditions in which this behavior will fire or not. - /// - private readonly Func behaviorSelectionPredicate; - - /// - /// In conjunction with the behavior selection predicate above, controls when this behavior will fire. - /// - private readonly TriggerType type; - - /// - /// Holds the action associated with this delegate, when the selector above returns true. - /// - private readonly Action onSessionSelected; - - /// - /// Initializes a new instance of the ProxyBehavior class. - /// - /// Gives the action to take when this behavior has been selected. - /// Controls in which conditions this behavior will fire. If null, this behavior will always be selected. - /// Governs how many sessions the behavior should be applied to, and whether there is a expiration time for the behavior. - /// In conjunction with the behavior selection predicate above, controls when this behavior will fire. - public ProxyBehavior( - Action action, - Func predicate = null, - BehaviorOptions options = null, - TriggerType type = TriggerType.All) - { - this.onSessionSelected = action; - this.behaviorSelectionPredicate = predicate ?? Selectors.Always(); - this.options = options ?? new BehaviorOptions(); - this.type = type; - } - - /// - /// Gets the predicate controlling the conditions in which this behavior will fire or not. - /// - public Func Selector - { - get { return this.behaviorSelectionPredicate; } - } - - /// - /// Gets the options for this behavior, including how many sessions the behavior should be applied to, - /// and whether there is a expiration time for the behavior. - /// - public BehaviorOptions Options - { - get { return this.options; } - } - - /// - /// Gets the circumstances in which this selector is intended to fire. - /// - public TriggerType TriggerFlags - { - get { return this.type; } - } - - /// - /// Execute fires the behavior associated with this selector. - /// - /// The session on which the behavior will be acting. - public void Execute(Session relatedSession) - { - this.options.DecrementSessionCount(); - - if (this.onSessionSelected != null) - { - this.onSessionSelected(relatedSession); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_FiddlerGif.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_FiddlerGif.dat deleted file mode 100644 index 06af2dfb5db57..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_FiddlerGif.dat and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_SimpleHTML.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_SimpleHTML.dat deleted file mode 100644 index 6a733b85fcbf9..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_SimpleHTML.dat +++ /dev/null @@ -1,5 +0,0 @@ -HTTP/1.1 200 OK -FiddlerTemplate: True -Content-Length: 51 - -This is a simple Fiddler-returned HTML page. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_TransPixel.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_TransPixel.dat deleted file mode 100644 index 3d09be55ec230..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/200_TransPixel.dat and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/204_NoContent.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/204_NoContent.dat deleted file mode 100644 index 7d074645bb6fe..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/204_NoContent.dat +++ /dev/null @@ -1,4 +0,0 @@ -HTTP/1.1 204 No Content -FiddlerTemplate: True -Content-Length: 0 - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/302_Redirect.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/302_Redirect.dat deleted file mode 100644 index a6a43b0d7419e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/302_Redirect.dat +++ /dev/null @@ -1,5 +0,0 @@ -HTTP/1.1 302 Redirect -FiddlerTemplate: True -Location: http://www.fiddler2.com/sandbox/FormAndCookie.asp -Content-Length: 0 - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/303_RedirectWithGet.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/303_RedirectWithGet.dat deleted file mode 100644 index cf608025906a5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/303_RedirectWithGet.dat +++ /dev/null @@ -1,5 +0,0 @@ -HTTP/1.1 303 Redirect Using GET -FiddlerTemplate: True -Location: http://www.fiddler2.com/sandbox/FormAndCookie.asp -Content-Length: 0 - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/304_NotModified.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/304_NotModified.dat deleted file mode 100644 index 92a80816b526f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/304_NotModified.dat +++ /dev/null @@ -1,4 +0,0 @@ -HTTP/1.1 304 Not Modified -FiddlerTemplate: True -Content-Length: 0 - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/307_RedirectWithMethod.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/307_RedirectWithMethod.dat deleted file mode 100644 index 54432d414bbb1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/307_RedirectWithMethod.dat +++ /dev/null @@ -1,5 +0,0 @@ -HTTP/1.1 307 Redirect using same Method -FiddlerTemplate: True -Location: http://www.fiddler2.com/sandbox/FormAndCookie.asp -Content-Length: 0 - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthBasic.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthBasic.dat deleted file mode 100644 index 87e47aabc977f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthBasic.dat +++ /dev/null @@ -1,7 +0,0 @@ -HTTP/1.1 401 Authentication Required -FiddlerTemplate: True -WWW-Authenticate: Basic realm="Fiddler" -Content-Type: text/html -Content-Length: 520 - -Fiddler: HTTP/401 Basic Server Auth Required. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthDigest.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthDigest.dat deleted file mode 100644 index e267853cd1f09..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/401_AuthDigest.dat +++ /dev/null @@ -1,7 +0,0 @@ -HTTP/1.1 401 Authentication Required -FiddlerTemplate: True -WWW-Authenticate: Digest realm="realm@example.com",qop="auth,auth-int",nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",opaque="5ccc069c403ebaf9f0171e9517f40e41" -Content-Type: text/html -Content-Length: 520 - -Fiddler: HTTP/401 Digest Server Auth Required. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/403_AuthDeny.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/403_AuthDeny.dat deleted file mode 100644 index 5f63a61846f0e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/403_AuthDeny.dat +++ /dev/null @@ -1,5 +0,0 @@ -HTTP/1.1 403 Access Denied -FiddlerTemplate: True -Content-Length: 520 - -Fiddler: HTTP/403 Access Denied. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/404_Plain.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/404_Plain.dat deleted file mode 100644 index d5b910637fce6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/404_Plain.dat +++ /dev/null @@ -1,6 +0,0 @@ -HTTP/1.1 404 Not Found -FiddlerTemplate: True -Content-Type: text/html -Content-Length: 520 - -Fiddler: HTTP/404 Not Found \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/407_ProxyAuthBasic.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/407_ProxyAuthBasic.dat deleted file mode 100644 index dcc418e735f96..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/407_ProxyAuthBasic.dat +++ /dev/null @@ -1,7 +0,0 @@ -HTTP/1.1 407 Proxy Auth Required -FiddlerTemplate: True -Proxy-Authenticate: Basic realm="Fiddler (just hit Ok)" -Content-Type: text/html -Content-Length: 520 - -Fiddler: HTTP/407 Proxy Auth Required. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/502_Unreachable.dat b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/502_Unreachable.dat deleted file mode 100644 index 1f57b04dfde1d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/ResponseTemplates/502_Unreachable.dat +++ /dev/null @@ -1,6 +0,0 @@ -HTTP/1.1 502 Unreachable Server -FiddlerTemplate: True -Content-Type: text/html -Content-Length: 520 - -Fiddler: HTTP/502 unreachable server. \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Selectors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Selectors.cs deleted file mode 100644 index e5a3d53b3c38a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/Selectors.cs +++ /dev/null @@ -1,449 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network -{ - using Fiddler; - using System; - - /// - /// Selectors are predicates over Fiddler.Session objects. This static class contains a good number of useful ones. - /// - public static class Selectors - { - /// - /// Always returns a predicate which returns true in every case. - /// - /// The relevant selector. - public static Func Always() - { - return Always; - } - - /// - /// Never returns a predicate which returns false in every case. - /// - /// The relevant selector. - public static Func Never() - { - return Never; - } - - /// - /// And returns a selector which is the logical AND value of the two provided selectors. - /// - /// The left-hand side predicate. - /// The right-hand side predicate. - /// The relevant selector. - public static Func And(this Func lhsPredicate, Func rhsPredicate) - { - return session => lhsPredicate(session) && rhsPredicate(session); - } - - /// - /// Or returns a selector which is the logical OR value of the two provided selectors. - /// - /// The left-hand side predicate. - /// The right-hand side predicate. - /// The relevant selector. - public static Func Or(this Func lhsPredicate, Func rhsPredicate) - { - return session => lhsPredicate(session) || rhsPredicate(session); - } - - /// - /// Alternating returns a predicate which returns true, then false, then true, and so forth. - /// - /// The initial state of the alternating selector. - /// The relevant selector. - public static Func Alternating(bool initialState = true) - { - return new AlternatingSelector(initialState).Tick; - } - - /// - /// Alternating returns a predicate which returns true, then false, then true, and so forth. - /// - /// The initial predicate. - /// The initial state of the alternating selector. - /// The relevant selector. - public static Func Alternating(this Func predicate, bool initialState = true) - { - return predicate.And(Selectors.Alternating(initialState)); - } - - /// - /// EveryNSessions returns a predicate which returns true once every n times. - /// - /// The period of the selector. - /// The relevant selector. - public static Func EveryNSessions(int n) - { - return new EveryNSessionsSelector(n).Tick; - } - - /// - /// EveryNSessions returns a predicate which returns true once every n times. - /// - /// The initial predicate. - /// The period of the selector. - /// The relevant selector. - public static Func EveryNSessions(this Func predicate, int n) - { - return predicate.And(Selectors.EveryNSessions(n)); - } - - /// - /// SkipNSessions returns a predicate which always returns true after n invocations. - /// - /// How many sessions to skip. - /// The relevant selector. - public static Func SkipNSessions(int n) - { - return new SkipNSessionsSelector(n).Tick; - } - - /// - /// SkipNSessions returns a predicate which always returns true after n invocations. - /// - /// The initial predicate. - /// How many sessions to skip. - /// The relevant selector. - public static Func SkipNSessions(this Func predicate, int n) - { - return predicate.And(Selectors.SkipNSessions(n)); - } - - /// - /// IfGet returns a selector on the GET verb. - /// - /// The relevant selector. - public static Func IfGet() - { - return session => session.HTTPMethodIs("GET"); - } - - /// - /// IfGet returns a selector that adds a test for the GET verb. - /// - /// The initial predicate. - /// The relevant selector. - public static Func IfGet(this Func predicate) - { - return predicate.And(Selectors.IfGet()); - } - - /// - /// IfHead returns a selector on the HEAD verb. - /// - /// The relevant selector. - public static Func IfHead() - { - return session => session.HTTPMethodIs("HEAD"); - } - - /// - /// IfHead returns a selector that adds a test for the HEAD verb. - /// - /// The initial predicate. - /// The relevant selector. - public static Func IfHead(this Func predicate) - { - return predicate.And(Selectors.IfHead()); - } - - /// - /// IfPost returns a selector on the POST verb. - /// - /// The relevant selector. - public static Func IfPost() - { - return session => session.HTTPMethodIs("POST"); - } - - /// - /// IfPost returns a selector that adds a test for the POST verb. - /// - /// The initial predicate. - /// The relevant selector. - public static Func IfPost(this Func predicate) - { - return predicate.And(Selectors.IfPost()); - } - - /// - /// IfPut returns a selector on the PUT verb. - /// - /// The relevant selector. - public static Func IfPut() - { - return session => session.HTTPMethodIs("PUT"); - } - - /// - /// IfPut returns a selector that adds a test for the PUT verb. - /// - /// The initial predicate. - /// The relevant selector. - public static Func IfPut(this Func predicate) - { - return predicate.And(Selectors.IfPut()); - } - - /// - /// IfDelete returns a selector on the DELETE verb. - /// - /// The relevant selector. - public static Func IfDelete() - { - return session => session.HTTPMethodIs("DELETE"); - } - - /// - /// IfDelete returns a selector that adds a test for the GET verb. - /// - /// The initial predicate. - /// The relevant selector. - public static Func IfDelete(this Func predicate) - { - return predicate.And(Selectors.IfDelete()); - } - - /// - /// IfUrlEquals returns a predicate which returns true if the URL in the session matches the given URL. - /// - /// The URL to match. - /// The relevant selector. - public static Func IfUrlEquals(string urlToMatch) - { - return session => session.url == urlToMatch; - } - - /// - /// IfUrlEquals returns a predicate which returns true if the URL in the session matches the given URL. - /// - /// The initial predicate. - /// The URL to match. - /// The relevant selector. - public static Func IfUrlEquals(this Func predicate, string urlToMatch) - { - return predicate.And(Selectors.IfUrlEquals(urlToMatch)); - } - - /// - /// IfUrlContains returns a predicate which returns true if the URL contains the given substring of a URL. - /// - /// The substring for which to search. - /// The relevant selector. - public static Func IfUrlContains(string urlSubstring) - { - return session => session.url.Contains(urlSubstring); - } - - /// - /// IfUrlContains returns a predicate which returns true if the URL contains the given substring of a URL. - /// - /// The initial predicate. - /// The substring for which to search. - /// The relevant selector. - public static Func IfUrlContains(this Func predicate, string urlSubstring) - { - return predicate.And(Selectors.IfUrlContains(urlSubstring)); - } - - /// - /// IfHostNameContains returns a predicate which returns true if the hostname contains the given substring. - /// - /// The substring for which to search. - /// The relevant selector. - public static Func IfHostNameContains(string hostNameSubstring) - { - return session => session.hostname.Contains(hostNameSubstring); - } - - /// - /// IfHostNameContains returns a predicate which returns true if the hostname contains the given substring. - /// - /// The initial predicate. - /// The substring for which to search. - /// The relevant selector. - public static Func IfHostNameContains(this Func predicate, string hostNameSubstring) - { - return predicate.And(Selectors.IfHostNameContains(hostNameSubstring)); - } - - /// - /// Always will always return true. - /// - /// The relevant session; unused. - /// True in every case. - private static bool Always(Session session) - { - return true; - } - - /// - /// Never will always return false. - /// - /// The relevant session; unused. - /// False in every case. - private static bool Never(Session session) - { - return false; - } - - /// - /// Helper class for the Alternating selector. - /// - private class AlternatingSelector - { - /// - /// Holds the state that will be returned with the next call to Tick - /// - private bool state; - - /// - /// Initializes a new instance of the AlternatingSelector class. - /// - /// The initial value of a call to Tick. - public AlternatingSelector(bool initialState) - { - this.state = initialState; - } - - /// - /// Tick returns the current value of the state parameter, switching it in the process. - /// - /// The session in question; unused. - /// The previous value of the state parameter. - public bool Tick(Session session) - { - bool returnState = this.state; - this.state = !this.state; - return returnState; - } - } - - /// - /// Helper class for the Alternating selector. - /// - private class PercentageSelector - { - /// - /// Holds the state that will be returned with the next call to Tick - /// - private double percentage; - double tState = 0; - /// - /// Initializes a new instance of the AlternatingSelector class. - /// - /// The initial value of a call to Tick. - public PercentageSelector(double percentage) - { - this.percentage = percentage; - } - - /// - /// Tick returns the current value of the state parameter, switching it in the process. - /// - /// The session in question; unused. - /// The previous value of the state parameter. - public bool Tick(Session session) - { - tState += percentage; - if (tState > 1.0) - { - tState -= 1; - return true; - } - return false; - } - } - - /// - /// Helper class for the EveryNSessions selectors - /// - private class EveryNSessionsSelector - { - /// - /// Holds the value which count must be divisible by in order for Tick to return true. - /// - private readonly int n; - - /// - /// Holds the count of the number of times tick has been called. - /// - private int count; - - /// - /// Initializes a new instance of the EveryNSessionsSelector class. - /// - /// Tick will return true every n times. - public EveryNSessionsSelector(int n) - { - this.count = 0; - this.n = n; - } - - /// - /// Tick returns true if the current count is divisible by count. - /// - /// The session in question; unused. - /// True if the current number of times Tick has been called is divisible by n; false otherwise. - public bool Tick(Session session) - { - return 0 == (++this.count % this.n); - } - } - - /// - /// Helper class for the SkipNSessions selectors - /// - private class SkipNSessionsSelector - { - /// - /// Holds the value which count must be greater than in order for Tick to return true. - /// - private readonly int n; - - /// - /// Holds the count of the number of times Tick has been called. - /// - private int count; - - /// - /// Initializes a new instance of the SkipNSessionsSelector class. - /// - /// Tick will return true after it has been called n times. - public SkipNSessionsSelector(int n) - { - this.count = 0; - this.n = n; - } - - /// - /// Tick returns true if the current call count is greater than n. - /// - /// The session in question; unused. - /// True if the current number of times Tick has been called is greater than n; false otherwise. - public bool Tick(Session session) - { - return ++this.count > this.n; - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/StockResponses.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/StockResponses.cs deleted file mode 100644 index a63479467efa4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/StockResponses.cs +++ /dev/null @@ -1,96 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network -{ - /// - /// StockResponses holds the filenames associated with several stock responses from HTTP servers. - /// - public static class StockResponses - { - /// - /// Returns status code 200 and a GIF file. - /// - public const string FiddlerGif200 = "200_FiddlerGif.dat"; - - /// - /// Returns status code 200 and a simple HTML file. - /// - public const string SimpleHTML200 = "200_SimpleHTML.dat"; - - /// - /// Returns status code 200 and a transparent pixel. - /// - public const string TransPixel200 = "200_TransPixel.dat"; - - /// - /// Returns status code 204 (No Content) and no content. - /// - public const string NoContent204 = "204_NoContent.dat"; - - /// - /// Returns status code 302 (Found) with a redirect. - /// - public const string Redirect302 = "302_Redirect.dat"; - - /// - /// Returns status code 303 (See Other) with a redirect. - /// - public const string RedirectWithGet303 = "303_RedirectWithGet.dat"; - - /// - /// Returns status code 304 (Not Modified) with no content. - /// - public const string NotModified304 = "304_NotModified.dat"; - - /// - /// Returns status code 307 (Temporary Redirect) with a redirection method. - /// - public const string RedirectWithMethod307 = "307_RedirectWithMethod.dat"; - - /// - /// Returns status code 401 (Unauthorized) asking for basic auth. - /// - public const string AuthBasic401 = "401_AuthBasic.dat"; - - /// - /// Returns status code 401 (Unauthorized) asking for Digest auth. - /// - public const string AuthDigest401 = "401_AuthDigest.dat"; - - /// - /// Returns status code 403 (Forbidden), indicating that access to this resource is denied. - /// - public const string AuthDeny403 = "403_AuthDeny.dat"; - - /// - /// Returns status code 404 (Not Found) with nothing else attached. - /// - public const string Plain404 = "404_Plain.dat"; - - /// - /// Returns status code 407 (Proxy Authentication Required), asking for basic auth. - /// - public const string ProxyAuthBasic407 = "407_ProxyAuthBasic.dat"; - - /// - /// Returns status code 502 (Bad Gateway) indicating there was an issue reaching the proxy server. - /// - public const string Unreachable502 = "502_Unreachable.dat"; - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/TriggerType.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/TriggerType.cs deleted file mode 100644 index 577911a6695db..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/HttpMangler/TriggerType.cs +++ /dev/null @@ -1,72 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network -{ - using System; - - /// - /// The TriggerType enumeration controls, on a brute scale, when a behavior will fire. - /// It is a bit flag enumeration, so multiple values can be specified at once. - /// - [Flags] - public enum TriggerType - { - /// - /// This behavior will never fire. This value cannot be combined with other flags. - /// - None = 0, - - /// - /// This behavior will fire before the request is tranmitted across the wire. - /// - BeforeRequest = 1 << 0, - - /// - /// This behavior will fire before the response from the server is delivered back to the client, - /// but only in error cases. - /// - BeforeReturningError = 1 << 1, - - /// - /// This behavior will fire before the response from server is delivered back to the client. - /// - BeforeResponse = 1 << 2, - - /// - /// This behavior will fire when the HTTP session has been completed. - /// - AfterSessionComplete = 1 << 3, - - /// - /// This behavior will fire when the response headers from the request have been delivered. - /// This happens prior to the full response being delivered. - /// - ResponseHeadersAvailable = 1 << 4, - - /// - /// This value contains all other values. When it is specified, this behavior will happen - /// for every sort of event. - /// - All = BeforeRequest - | BeforeReturningError - | BeforeResponse - | AfterSessionComplete - | ResponseHeadersAvailable, - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Actions.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Actions.cs deleted file mode 100644 index ae2619267d0a4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Actions.cs +++ /dev/null @@ -1,74 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Fiddler; -using System; - -namespace Microsoft.WindowsAzure.Test.Network -{ - /// - /// Class to provide Actions for Storage Traffic - /// - public class Actions - { - /// - /// Action to throttle a table request - /// - /// a Action to throttle the given request - public static Action BreakSession = relevantSession => - { - relevantSession["x-breakrequest"] = "breaking for abort"; - }; - - /// - /// Action to throttle a table request - /// - public static Action ThrottleTableRequest = session => - { - string payload = String.Format(TableErrorPayload, "ServerBusy", "The server is busy..", Guid.NewGuid().ToString(), DateTime.UtcNow.ToString("o")); - session.oRequest.FailSession(503, "ServerBusy", payload); - }; - - /// - /// Action to throttle a blob or queue request - /// - public static Action ThrottleBlobQueueRequest = session => - { - string payload = String.Format(StorageErrorPayload, "ServerBusy", "The server is busy..", Guid.NewGuid().ToString(), DateTime.UtcNow.ToString("o")); - session.oRequest.FailSession(503, "ServerBusy", payload); - }; - - /// - /// String representing the Error Payload - /// - public static string TableErrorPayload = @"" + - @"" + - "{0}\r\n" + - @"" + - "{1}\r\nRequestId:{2}\r\nTime:{3}" + - "\r\n"; - - /// - /// String representing the Blob and QUEUE Error Payload - /// - public static string StorageErrorPayload = @"" + - "\r\n" + - "{0}\r\n" + - "{1}\r\nRequestId:{2}\r\nTime:{3}\r\n" + - ""; - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/BlobBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/BlobBehaviors.cs deleted file mode 100644 index e9193803a3c97..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/BlobBehaviors.cs +++ /dev/null @@ -1,28 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - -namespace Microsoft.WindowsAzure.Test.Network -{ - /// - /// BlobBehaviors are pre-built ProxyBehaviors for use with the Azure Storage Blob Front End. - /// - public static class BlobBehaviors - { - - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Properties/AssemblyInfo.cs deleted file mode 100644 index 4b7b48c04ed4f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("XStoreMangler.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("26db5ac8-e1e1-4e3d-bcd0-da6e55b21407")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/StorageConstants.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/StorageConstants.cs deleted file mode 100644 index 68197c45e8557..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/StorageConstants.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - - - -namespace Microsoft.WindowsAzure.Test.Network -{ - /// - /// StorageConstants holds well-known information about XStore. - /// - public static class StorageConstants - { - /// - /// The root blob storage DNS name. - /// - public const string BlobBaseDnsName = "blob.core.windows.net"; - - /// - /// The root queue DNS name. - /// - public const string QueueBaseDnsName = "queue.core.windows.net"; - - /// - /// The root table storage DNS name. - /// - public const string TableBaseDnsName = "table.core.windows.net"; - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableBehaviors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableBehaviors.cs deleted file mode 100644 index 07e4e0e99e78e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableBehaviors.cs +++ /dev/null @@ -1,254 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network -{ - using Fiddler; - using Microsoft.WindowsAzure.Test.Network.Behaviors; - using System; - using System.Linq; - using System.Text.RegularExpressions; - using System.Xml.Linq; - - /// - /// TableBehaviors contains behaviors for Azure Storage tables - /// - public static class TableBehaviors - { - private static readonly Regex tableNameRegex = new Regex(@"/Tables\('([^']+)'\)", RegexOptions.Compiled); - - /// - /// CreateTableOk returns a behavior which causes all create requests for table traffic to return successfully. - /// - /// A new behavior. - public static ProxyBehavior CreateTableOk() - { - return TamperBehaviors.TamperAllRequestsIf(session => GetTableWithCode(session, 201), Selectors.IfPost().ForTableTraffic()); - } - - /// - /// CreateTableOk returns a behavior which causes all GET requests for table creation traffic to return successfully. - /// - /// A new behavior. - public static ProxyBehavior GetTableOk() - { - return TamperBehaviors.TamperAllRequestsIf(session => GetTableWithCode(session, 200), Selectors.IfGet().ForTableTraffic()); - } - - /// - /// CreateTableErrorTableAlreadyExists returns a behavior saying the request failed with 409 (conflict) and substatus of "already exists" - /// - /// A new behavior. - public static ProxyBehavior CreateTableErrorTableAlreadyExists() - { - return TamperBehaviors.TamperAllRequestsIf( - session => CreateTableError(session, 409, "TableAlreadyExists", "The table specified already exists."), - Selectors.IfPost().ForTableTraffic()); - } - - /// - /// CreateTableErrorTableBeingDeleted returns a behavior saying the request failed with 409 (conflict) and substatus of "being deleted" - /// - /// A new behavior. - public static ProxyBehavior CreateTableErrorTableBeingDeleted() - { - return TamperBehaviors.TamperAllRequestsIf( - session => CreateTableError(session, 409, "TableBeingDeleted", "The table specified is in the process of being deleted."), - Selectors.IfPost().ForTableTraffic()); - } - - /// - /// GetTableNotFound returns a behavior saying the request failed with 404 (not found) - /// - /// A new behavior. - public static ProxyBehavior GetTableNotFound() - { - return TamperBehaviors.TamperAllRequestsIf( - session => CreateTableError(session, 404, "ResourceNotFound", "The specified resource does not exist."), - Selectors.IfGet().ForTableTraffic()); - } - - /// - /// EchoTableEntry echos back the contents that were sent to the server. - /// - /// A new behavior. - public static ProxyBehavior EchoTableEntry() - { - return TamperBehaviors.TamperAllRequestsIf(EchoEntry, Selectors.IfPost().ForTableTraffic()); - } - - private static void EchoEntry(Session session) - { - Uri hostName = new Uri(string.Format("http://{0}/", session.oRequest["Host"])); - Uri tableUrl = new Uri(session.fullUrl); - string requestString = session.GetRequestBodyAsString(); - - string timestamp = DateTime.UtcNow.ToString("o"); - string etag = string.Format("W/\"datetime'{0}'\"", Uri.EscapeDataString(timestamp)); - - XElement request = XElement.Parse(requestString); - - request.SetAttributeValue(XNamespace.Xml + "base", hostName.AbsoluteUri); - request.SetAttributeValue(TableConstants.Metadata + "etag", Uri.EscapeDataString(etag)); - - string partitionKey = request.Descendants(TableConstants.OData + "PartitionKey").Single().Value; - string rowKey = request.Descendants(TableConstants.OData + "RowKey").Single().Value; - - Uri entryUri = new Uri(string.Format( - "{0}(PartitionKey='{1}',RowKey='{2}')", - tableUrl.AbsoluteUri, - Uri.EscapeUriString(partitionKey), - Uri.EscapeUriString(rowKey))); - - XElement timestampElement = request.Descendants(TableConstants.OData + "Timestamp").Single(); - timestampElement.Value = timestamp; - - XElement updatedElement = request.Descendants(TableConstants.Atom + "updated").Single(); - updatedElement.Value = timestamp; - - XElement idElement = request.Descendants(TableConstants.Atom + "id").Single(); - idElement.Value = entryUri.AbsoluteUri; - - // Add link - XElement linkElement = new XElement( - TableConstants.Atom + "link", - new XAttribute("rel", "edit"), - new XAttribute("href", entryUri.PathAndQuery.Substring(1))); - idElement.AddAfterSelf(linkElement); - - // Add category - string accountName = hostName.Host.Substring(0, hostName.Host.IndexOf('.')); - string categoryName = accountName + "." + tableUrl.PathAndQuery.Substring(1); - idElement.AddAfterSelf(TableConstants.GetCategory(categoryName)); - - // mark that we're going to tamper with it - session.utilCreateResponseAndBypassServer(); - - session.oResponse.headers = CreateResponseHeaders(entryUri.AbsoluteUri); - session.oResponse.headers["ETag"] = etag; - - session.responseCode = 201; - - string responseString = request.ToString(); - session.utilSetResponseBody(responseString); - } - - /// - /// GetTableWithCode tampers with with the request to return the specific table and a success code. - /// - /// - /// - private static void GetTableWithCode(Session session, int statusCode) - { - // Find relevant facts about this table creation. - Uri hostName = new Uri(string.Format("http://{0}/", session.oRequest["Host"])); - string requestString = session.GetRequestBodyAsString(); - - string tableName = null; - string tableUri = null; - if (string.IsNullOrEmpty(requestString)) - { - tableName = tableNameRegex.Match(session.url).Groups[1].Value; - } - else - { - XElement request = XElement.Parse(requestString); - tableName = request.Descendants(TableConstants.OData + "TableName").Single().Value; - tableUri = new Uri(hostName, string.Format("/Tables('{0}')", tableName)).AbsoluteUri; - } - - // mark that we're going to tamper with it - session.utilCreateResponseAndBypassServer(); - - session.oResponse.headers = CreateResponseHeaders(tableUri); - session.responseCode = statusCode; - - // Create the response XML - XElement response = TableConstants.GetEntry(hostName.AbsoluteUri); - - response.Add(new XElement(TableConstants.Atom + "id", session.fullUrl)); - response.Add(new XElement(TableConstants.Title)); - response.Add(new XElement(TableConstants.Atom + "updated", DateTime.UtcNow.ToString("o"))); - response.Add(TableConstants.Author); - - response.Add(TableConstants.GetLink(tableName)); - - string accountName = hostName.Host.Substring(0, hostName.Host.IndexOf('.')); - response.Add(TableConstants.GetCategory(accountName + ".Tables")); - - // Add in the most important part -- the table name. - response.Add(new XElement( - TableConstants.Atom + "content", - new XAttribute("type", "application/xml"), - new XElement( - TableConstants.Metadata + "properties", - new XElement( - TableConstants.OData + "TableName", - tableName)))); - - string responseString = response.ToString(); - session.utilSetResponseBody(responseString); - } - - /// - /// CreateTableError creates an error response from a table API. - /// - /// The session with which to tamper. - /// The error code to return - /// The string name for the error - /// The long error message to be returned. - private static void CreateTableError(Session session, int statusCode, string messageCode, string message) - { - session.utilCreateResponseAndBypassServer(); - session.oResponse.headers = CreateResponseHeaders(null); - session.responseCode = statusCode; - - session.utilSetResponseBody( - TableConstants.GetError( - messageCode, - string.Format( - "{0}\r\nRequestId:{1}\r\nTime:{2}", - message, - Guid.Empty.ToString(), - DateTime.UtcNow.ToString("o"))).ToString()); - } - - /// - /// CreateResponseHeaders returns a set of common response headers. - /// - /// The table URI to include in the Location header. Null of empty if no location. - /// - private static HTTPResponseHeaders CreateResponseHeaders(string tableUri) - { - HTTPResponseHeaders headers = new HTTPResponseHeaders(); - headers["Transfer-Encoding"] = "chunked"; - headers["Date"] = DateTime.UtcNow.ToString("R"); - headers["Cache-Control"] = "no-cache"; - - if (!string.IsNullOrEmpty(tableUri)) - { - headers["Location"] = tableUri; - } - - headers["Content-Type"] = "application/atom+xml;charset=utf-8"; - headers["x-ms-version"] = TableConstants.XMsVersion; - headers["x-ms-request-id"] = Guid.Empty.ToString(); - - return headers; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableConstants.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableConstants.cs deleted file mode 100644 index c9c7892061d24..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/TableConstants.cs +++ /dev/null @@ -1,142 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network -{ - - using System.Xml.Linq; - - /// - /// Constants that are well-known in XTable - /// - public static class TableConstants - { - /// - /// The ADO.NET (OData) namespace - /// - public static readonly XNamespace OData = "http://schemas.microsoft.com/ado/2007/08/dataservices"; - - /// - /// OData metadata - /// - - public static readonly XNamespace Metadata = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"; - - /// - /// Root namespace for Atom content - /// - public static readonly XNamespace Atom = "http://www.w3.org/2005/Atom"; - - /// - /// Entry element - /// - public static readonly XElement Entry = new XElement(Atom + "entry", - new XAttribute(XNamespace.Xmlns + "d", OData.NamespaceName), - new XAttribute(XNamespace.Xmlns + "m", Metadata.NamespaceName), - new XAttribute("xmlns", Atom.NamespaceName)); - - /// - /// Title element - /// - public static readonly XElement Title = new XElement(Atom + "title", new XAttribute("type", "text")); - - /// - /// Author element - /// - public static readonly XElement Author = new XElement(Atom + "author", new XElement(Atom + "name")); - - /// - /// Content element - /// - public static readonly XElement Content = new XElement(Atom + "content", new XAttribute("type", "application/xml")); - - /// - /// Properties element - /// - public static readonly XElement Properties = new XElement(Metadata + "properties"); - - /// - /// Version string - /// - public const string XMsVersion = "2009-09-19"; - - /// - /// GetEntry returns a new Entry element - /// - /// The value of the xml:base attribute - /// A new XElement - public static XElement GetEntry(string @base) - { - XElement element = new XElement(Entry); - element.SetAttributeValue(XNamespace.Xml + "base", @base); - return element; - } - - /// - /// GetCategory returns the category element of an atom feed - /// - /// The term to use - /// A new XElement - public static XElement GetCategory(string term) - { - return new XElement(Atom + "category", - new XAttribute("term", term), - new XAttribute("scheme", "http://schemas.microsoft.com/ado/2007/08/dataservices/scheme")); - } - - /// - /// GetError retuns the error element of an Azure Storage error - /// - /// The code to return - /// The message to return - /// A new XElement - public static XElement GetError(string code, string message) - { - return new XElement(Metadata + "error", - new XAttribute("xmlns", Metadata.NamespaceName), - new XElement(Metadata + "code", code), - new XElement(Metadata + "message", - new XAttribute(XNamespace.Xml + "lang", "en-US"), - message)); - } - - /// - /// GetLink returns the link element for a table entry. - /// - /// The referenced table - /// A new XElement - public static XElement GetLink(string tableName) - { - return new XElement( - Atom + "link", - new XAttribute("rel", "edit"), - new XAttribute("title", "Tables"), - new XAttribute("href", string.Format("Tables('{0}')", tableName))); - } - - /// - /// GetProperty returns an OData property. - /// - /// The property name - /// The property value - /// A new XElement - public static XElement GetProperty(string name, string value) - { - return new XElement(OData + name, value); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreMangler.csproj b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreMangler.csproj deleted file mode 100644 index 9991d2ed7db61..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreMangler.csproj +++ /dev/null @@ -1,66 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {6EB781C5-6D91-48F0-8F79-EC1E4EDAAF7B} - Library - Properties - Microsoft.WindowsAzure.Test.Network - XStoreMangler - v4.0 - 512 - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - 1685 - $(OutputPath)\$(AssemblyName).xml - true - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - 1685 - $(OutputPath)\$(AssemblyName).xml - true - - - - ..\Dependencies\DotNet2\FiddlerCore.dll - - - - - - - - - - - - - - - - - - {ca607e8f-2906-4065-a1a9-4a3733f0cc31} - HttpMangler - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreSelectors.cs b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreSelectors.cs deleted file mode 100644 index c905d89522abb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/XStoreSelectors.cs +++ /dev/null @@ -1,85 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Test.Network -{ - using Fiddler; - using System; - - /// - /// XStoreSelectors are selectors and selector extensions that handle Azure Storage traffic. - /// - public static class XStoreSelectors - { - /// - /// BlobTraffic selects traffic intended for the Azure Storage Blob Front End. - /// - /// The relevant selector. - public static Func BlobTraffic() - { - return Selectors.IfHostNameContains(StorageConstants.BlobBaseDnsName); - } - - /// - /// ForBlobTraffic adds a selector that selects traffic intended for the Azure Storage Blob Front E. - /// - /// The initial predicate. - /// The relevant selector. - public static Func ForBlobTraffic(this Func predicate) - { - return predicate.IfHostNameContains(StorageConstants.BlobBaseDnsName); - } - - /// - /// TableTraffic selects traffic intended for the Azure Storage Table Front End. - /// - /// The relevant selector. - public static Func TableTraffic() - { - return Selectors.IfHostNameContains(StorageConstants.TableBaseDnsName); - } - - /// - /// ForTableTraffic selects traffic intended for the Azure Storage Table Front End. - /// - /// The initial predicate. - /// The relevant selector. - public static Func ForTableTraffic(this Func predicate) - { - return predicate.IfHostNameContains(StorageConstants.TableBaseDnsName); - } - - /// - /// QueueTraffic selects traffic intended for the Azure Storage Queue Front End. - /// - /// The relevant selector. - public static Func QueueTraffic() - { - return Selectors.IfHostNameContains(StorageConstants.QueueBaseDnsName); - } - - /// - /// ForQueueTraffic selects traffic intended for the Azure Storage Queue Front End. - /// - /// The initial predicate. - /// The relevant selector - public static Func ForQueueTraffic(this Func predicate) - { - return predicate.IfHostNameContains(StorageConstants.QueueBaseDnsName); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/app.config b/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/app.config deleted file mode 100644 index e59af44de2ddb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/FaultInjection/XStoreMangler/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobAnalyticsUnitTests.cs deleted file mode 100644 index 63c3a5b764bf7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobAnalyticsUnitTests.cs +++ /dev/null @@ -1,364 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public BlobAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudBlobClient client = GenerateCloudBlobClient(); - startProperties = client.GetServicePropertiesAsync().AsTask().Result; - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.SetServicePropertiesAsync(startProperties).AsTask().Wait(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - [TestMethod] - /// [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsRoundTripAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - /// [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsDisableAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Default Service Version")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsDefaultServiceVersionAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - props.DefaultServiceVersion = "2009-09-19"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = "2011-08-18"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = "2012-02-12"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = null; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsLoggingOperationsAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsMetricsLevelAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsRetentionPoliciesAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobCancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobCancellationUnitTests.cs deleted file mode 100644 index bb5351bfadd56..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobCancellationUnitTests.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Windows.Foundation; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobCancellationUnitTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Cancel blob download to stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToStreamCancelAsync() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(originalBlob.AsInputStream()); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext operationContext = new OperationContext(); - IAsyncAction action = blob.DownloadToStreamAsync(downloadedBlob.AsOutputStream(), null, null, operationContext); - await Task.Delay(100); - action.Cancel(); - try - { - await action; - } - catch (Exception) - { - Assert.AreEqual(operationContext.LastResult.Exception.Message, "A task was canceled."); - Assert.AreEqual(operationContext.LastResult.HttpStatusCode, 306); - //Assert.AreEqual(operationContext.LastResult.HttpStatusMessage, "Unused"); - } - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Cancel upload from stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamCancelAsync() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - OperationContext operationContext = new OperationContext(); - IAsyncAction action = blob.UploadFromStreamAsync(originalBlob.AsInputStream(), null, null, operationContext); - await Task.Delay(100); - action.Cancel(); - try - { - await action; - } - catch (Exception) - { - Assert.AreEqual(operationContext.LastResult.Exception.Message, "A task was canceled."); - Assert.AreEqual(operationContext.LastResult.HttpStatusCode, 306); - //Assert.AreEqual(operationContext.LastResult.HttpStatusMessage, "Unused"); - } - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobReadStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobReadStreamTest.cs deleted file mode 100644 index fd05b67107497..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobReadStreamTest.cs +++ /dev/null @@ -1,385 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobReadStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - using (IInputStream blobStream = await blob.OpenReadAsync()) - { - await TestHelper.AssertStreamsAreEqualAsync(wholeBlob.AsInputStream(), blobStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Download a blob using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - IRandomAccessStreamWithContentType readStream = await blob.OpenReadAsync(); - using (Stream blobStream = readStream.AsStreamForRead()) - { - TestHelper.AssertStreamsAreEqual(wholeBlob, blobStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadLockToETagTestAsync() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - OperationContext opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - long length = blobStreamForRead.Length; - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenReadAsync(accessCondition, null, opContext), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadLockToETagTestAsync() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - OperationContext opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - long length = blobStreamForRead.Length; - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenReadAsync(accessCondition, null, opContext), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - private static async Task BlobReadStreamSeekAndCompareAsync(IRandomAccessStreamWithContentType blobStream, byte[] bufferToCompare, ulong offset, uint readSize, uint expectedReadCount) - { - byte[] testBuffer = new byte[readSize]; - - IBuffer testBufferAsIBuffer = testBuffer.AsBuffer(); - await blobStream.ReadAsync(testBufferAsIBuffer, readSize, InputStreamOptions.None); - Assert.AreEqual(expectedReadCount, testBufferAsIBuffer.Length); - - long bufferOffset = (long)offset; - for (int i = 0; i < expectedReadCount; i++, bufferOffset++) - { - Assert.AreEqual(bufferToCompare[bufferOffset], testBuffer[i]); - } - - return expectedReadCount; - } - - private static async Task BlobReadStreamSeekTestAsync(IRandomAccessStreamWithContentType blobStream, long streamReadSize, byte[] bufferToCompare) - { - int attempts = 1; - ulong position = 0; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 512, 512); - Assert.AreEqual(position, blobStream.Position); - position = (ulong)(bufferToCompare.Length - 128); - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 128); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position = 4096; - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position += 4096; - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - Assert.AreEqual(position, blobStream.Position); - position -= 4096; - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 128, 128); - Assert.AreEqual(position, blobStream.Position); - position = (ulong)(streamReadSize + 4096 - 512); - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - Assert.AreEqual(position, blobStream.Position); - position -= 1024; - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 2048, 2048); - Assert.AreEqual(position, blobStream.Position); - position = (ulong)(bufferToCompare.Length - 128); - blobStream.Seek(position); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 128); - Assert.AreEqual(position, blobStream.Position); - return attempts; - } - - [TestMethod] - /// [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadStreamSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - OperationContext opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - int attempts = await BlobReadStreamSeekTestAsync(blobStream, blob.StreamMinimumReadSizeInBytes, buffer); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadStreamSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - } - - OperationContext opContext = new OperationContext(); - using (IRandomAccessStreamWithContentType blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - int attempts = await BlobReadStreamSeekTestAsync(blobStream, blob.StreamMinimumReadSizeInBytes, buffer); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobStreamTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobStreamTests.cs deleted file mode 100644 index 95700a2b05449..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobStreamTests.cs +++ /dev/null @@ -1,314 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobStreamTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - //[Description("BlobSeek")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream.AsInputStream(), null, null, null); - using (IInputStream blobStream = await blob.OpenReadAsync()) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - blobStreamForRead.Seek(2048, 0); - byte[] buff = new byte[100]; - int numRead = await blobStreamForRead.ReadAsync(buff, 0, 100); - Assert.AreEqual(numRead, 0); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenWriteTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (ICloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream.AsStreamForWrite(); - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - await blobStreamForWrite.FlushAsync(); - - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - await blob.DownloadRangeToStreamAsync(dstStream.AsOutputStream(), null, null); - - MemoryStream memStream = new MemoryStream(buffer); - TestHelper.AssertStreamsAreEqual(memStream, dstStream); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenReadTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream.AsInputStream()); - - IInputStream dstStream = await blob.OpenReadAsync(); - using (Stream dstStreamForRead = dstStream.AsStreamForRead()) - { - TestHelper.AssertStreamsAreEqual(srcStream, dstStreamForRead); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("OpenReadWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenReadWriteTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - using (ICloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream.AsStreamForWrite(); - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - await blobStreamForWrite.FlushAsync(); - } - - using (IInputStream dstStream = await blob.OpenReadAsync()) - { - Stream dstStreamForRead = dstStream.AsStreamForRead(); - MemoryStream memoryStream = new MemoryStream(buffer); - TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("OpenWriteSeekRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenWriteSeekReadTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - MemoryStream memoryStream = new MemoryStream(buffer); - using (ICloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream.AsStreamForWrite(); - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - - Assert.AreEqual(blobStreamForWrite.Position, 2048); - - blobStreamForWrite.Seek(1024, 0); - memoryStream.Seek(1024, 0); - Assert.AreEqual(blobStreamForWrite.Position, 1024); - - byte[] testBuffer = GetRandomBuffer(1024); - - await memoryStream.WriteAsync(testBuffer, 0, 1024); - await blobStreamForWrite.WriteAsync(testBuffer, 0, 1024); - Assert.AreEqual(blobStreamForWrite.Position, memoryStream.Position); - - await blobStreamForWrite.FlushAsync(); - } - - using (IInputStream dstStream = await blob.OpenReadAsync()) - { - Stream dstStreamForRead = dstStream.AsStreamForRead(); - TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("Read when opened in OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobReadWhenOpenWriteAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - bool thrown = false; - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - MemoryStream memoryStream = new MemoryStream(buffer); - using (IOutputStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream.AsStreamForWrite(); - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - byte[] testBuffer = new byte[2048]; - try - { - await blobStreamForWrite.ReadAsync(testBuffer, 0, 2048); - } - catch (NotSupportedException) - { - thrown = true; - } - - Assert.IsTrue(thrown); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("Write when opened in OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobWriteWhenOpenReadAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream.AsInputStream()); - bool thrown = false; - byte[] testBuffer = new byte[2048]; - using (IInputStream blobStream = await blob.OpenReadAsync()) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - try - { - await blobStreamForRead.WriteAsync(testBuffer, 0, 2048); - } - catch (NotSupportedException) - { - thrown = true; - } - - Assert.IsTrue(thrown); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobTestBase.cs deleted file mode 100644 index 66e5ba914a7d2..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobTestBase.cs +++ /dev/null @@ -1,97 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - public partial class BlobTestBase : TestBase - { - public static async Task WaitForCopyAsync(ICloudBlob blob) - { - bool copyInProgress = true; - while (copyInProgress) - { - await Task.Delay(1000); - await blob.FetchAttributesAsync(); - copyInProgress = (blob.CopyState.Status == CopyStatus.Pending); - } - } - - public static async Task> CreateBlobsAsync(CloudBlobContainer container, int count, BlobType type) - { - string name; - List blobs = new List(); - for (int i = 0; i < count; i++) - { - switch (type) - { - case BlobType.BlockBlob: - name = "bb" + Guid.NewGuid().ToString(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference(name); - await blockBlob.PutBlockListAsync(new string[] { }); - blobs.Add(name); - break; - - case BlobType.PageBlob: - name = "pb" + Guid.NewGuid().ToString(); - CloudPageBlob pageBlob = container.GetPageBlobReference(name); - await pageBlob.CreateAsync(0); - blobs.Add(name); - break; - } - } - return blobs; - } - - public static async Task UploadTextAsync(ICloudBlob blob, string text, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - byte[] textAsBytes = encoding.GetBytes(text); - using (MemoryStream stream = new MemoryStream()) - { - await stream.WriteAsync(textAsBytes, 0, textAsBytes.Length); - if (blob.BlobType == BlobType.PageBlob) - { - int lastPageSize = (int)(stream.Length % 512); - if (lastPageSize != 0) - { - byte[] padding = new byte[512 - lastPageSize]; - await stream.WriteAsync(padding, 0, padding.Length); - } - } - - stream.Seek(0, SeekOrigin.Begin); - blob.ServiceClient.ParallelOperationThreadCount = 2; - await blob.UploadFromStreamAsync(stream.AsInputStream(), accessCondition, options, operationContext); - } - } - - public static async Task DownloadTextAsync(ICloudBlob blob, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream.AsOutputStream(), accessCondition, options, operationContext); - byte[] buffer = stream.ToArray(); - return encoding.GetString(buffer, 0, buffer.Length); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobUploadDownloadTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobUploadDownloadTest.cs deleted file mode 100644 index 73e25956765b0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobUploadDownloadTest.cs +++ /dev/null @@ -1,576 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using Windows.Storage; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobUploadDownloadTest : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - this.testContainer.CreateIfNotExistsAsync().AsTask().Wait(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.DeleteIfExistsAsync().AsTask().Wait(); - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - //[Description("Download a specific range of the blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobDownloadToStreamRangeTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob.AsInputStream()); - - byte[] testBuffer = new byte[1024]; - MemoryStream blobStream = new MemoryStream(testBuffer); - Exception ex = await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadRangeToStreamAsync(blobStream.AsOutputStream(), 0, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(ArgumentOutOfRangeException)); - await blob.DownloadRangeToStreamAsync(blobStream.AsOutputStream(), 0, 1024); - Assert.AreEqual(blobStream.Position, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream, wholeBlob, 0, 0, 1024); - - CloudPageBlob blob2 = this.testContainer.GetPageBlobReference("blob1"); - MemoryStream blobStream2 = new MemoryStream(testBuffer); - ex = await TestHelper.ExpectedExceptionAsync( - async () => await blob2.DownloadRangeToStreamAsync(blobStream.AsOutputStream(), 1024, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(ArgumentOutOfRangeException)); - await blob2.DownloadRangeToStreamAsync(blobStream2.AsOutputStream(), 1024, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream2, wholeBlob, 0, 1024, 1024); - - AssertAreEqual(blob, blob2); - } - } - - [TestMethod] - //[Description("Upload a stream to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobUploadFromStreamTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream.AsInputStream()); - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - await blob.DownloadRangeToStreamAsync(dstStream.AsOutputStream(), null, null); - TestHelper.AssertStreamsAreEqual(srcStream, dstStream); - } - } - - [TestMethod] - //[Description("Upload from text to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobUploadWithoutMD5ValidationAndStoreBlobContentTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - BlobRequestOptions options = new BlobRequestOptions(); - options.DisableContentMD5Validation = false; - options.StoreBlobContentMD5 = false; - OperationContext context = new OperationContext(); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream.AsInputStream(), null, options, context); - await blob.FetchAttributesAsync(); - string md5 = blob.Properties.ContentMD5; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - await blob.SetPropertiesAsync(null, options, context); - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToStreamAsync(dstStream.AsOutputStream(), null, null, null, options, context), - context, - "Try to Download a stream with a corrupted md5 and DisableMD5Validation set to false", - HttpStatusCode.OK); - - options.DisableContentMD5Validation = true; - await blob.SetPropertiesAsync(null, options, context); - byte[] testBuffer2 = new byte[2048]; - MemoryStream dstStream2 = new MemoryStream(testBuffer2); - await blob.DownloadRangeToStreamAsync(dstStream2.AsOutputStream(), null, null, null, options, context); - } - } - - [TestMethod] - /// [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadDownloadFileAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoUploadDownloadFileAsync(blob, 0); - await this.DoUploadDownloadFileAsync(blob, 4096); - await this.DoUploadDownloadFileAsync(blob, 4097); - } - - [TestMethod] - /// [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadDownloadFileAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoUploadDownloadFileAsync(blob, 0); - await this.DoUploadDownloadFileAsync(blob, 4096); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.DoUploadDownloadFileAsync(blob, 4097), - "Page blobs must be 512-byte aligned"); - } - - private async Task DoUploadDownloadFileAsync(ICloudBlob blob, int fileSize) - { - StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder; - StorageFile inputFile = await tempFolder.CreateFileAsync("input.file", CreationCollisionOption.GenerateUniqueName); - StorageFile outputFile = await tempFolder.CreateFileAsync("output.file", CreationCollisionOption.GenerateUniqueName); - - try - { - byte[] buffer = GetRandomBuffer(fileSize); - using (Stream file = await inputFile.OpenStreamForWriteAsync()) - { - await file.WriteAsync(buffer, 0, buffer.Length); - } - - await blob.UploadFromFileAsync(inputFile); - - OperationContext context = new OperationContext(); - await blob.UploadFromFileAsync(inputFile, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - context = new OperationContext(); - await blob.DownloadToFileAsync(outputFile, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - using (Stream inputFileStream = await inputFile.OpenStreamForReadAsync(), - outputFileStream = await outputFile.OpenStreamForReadAsync()) - { - TestHelper.AssertStreamsAreEqual(inputFileStream, outputFileStream); - } - } - finally - { - inputFile.DeleteAsync().AsTask().Wait(); - outputFile.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 4 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 1 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 2 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 512, 0, 511); - } - - [TestMethod] - /// [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 4 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 1 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 2 * 512, 2 * 512); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.DoUploadFromByteArrayTestAsync(blob, 512, 0, 511), - "Page blobs must be 512-byte aligned"); - } - - private async Task DoUploadFromByteArrayTestAsync(ICloudBlob blob, int bufferSize, int bufferOffset, int count) - { - byte[] buffer = GetRandomBuffer(bufferSize); - byte[] downloadedBuffer = new byte[bufferSize]; - int downloadLength; - - await blob.UploadFromByteArrayAsync(buffer, bufferOffset, count); - downloadLength = await blob.DownloadToByteArrayAsync(downloadedBuffer, 0); - - Assert.AreEqual(count, downloadLength); - - for (int i = 0; i < count; i++) - { - Assert.AreEqual(buffer[i + bufferOffset], downloadedBuffer[i]); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToByteArrayAsyncOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, true); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadToByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadToByteArrayAsyncOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, true); - } - - private async Task DoDownloadToByteArrayAsyncTest(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, bool isOverload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (!isOverload) - { - await blob.UploadFromStreamAsync(originalBlob.AsInputStream()); - downloadLength = await blob.DownloadToByteArrayAsync(resultBuffer, bufferOffset); - } - else - { - await blob.UploadFromStreamAsync(originalBlob.AsInputStream()); - OperationContext context = new OperationContext(); - downloadLength = await blob.DownloadToByteArrayAsync(resultBuffer, bufferOffset, null, null, context); - } - - int downloadSize = Math.Min(blobSize, bufferSize - bufferOffset); - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < blob.Properties.Length; i++) - { - Assert.AreEqual(buffer[i], resultBuffer[bufferOffset + i]); - } - - for (int j = 0; j < bufferOffset; j++) - { - Assert.AreEqual(0, resultBuffer2[j]); - } - - if (bufferOffset + blobSize < bufferSize) - { - for (int k = bufferOffset + blobSize; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer2[k]); - } - } - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayAsyncOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, true); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayAsyncOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, true); - } - - /// - /// Single put blob and get blob. - /// - /// The blob size. - /// The output buffer size. - /// The output buffer offset. - /// The blob offset. - /// Length of the data range to download. - /// True when the overloaded method for DownloadRangeToByteArrayAsync is called. False when the basic method is called. - private async Task DoDownloadRangeToByteArrayAsyncTest(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, long? blobOffset, long? length, bool isOverload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (!isOverload) - { - await blob.UploadFromStreamAsync(originalBlob.AsInputStream()); - downloadLength = await blob.DownloadRangeToByteArrayAsync(resultBuffer, bufferOffset, blobOffset, length); - } - else - { - await blob.UploadFromStreamAsync(originalBlob.AsInputStream()); - OperationContext context = new OperationContext(); - downloadLength = await blob.DownloadRangeToByteArrayAsync(resultBuffer, bufferOffset, blobOffset, length, null, null, context); - } - - int downloadSize = Math.Min(blobSize - (int)(blobOffset.HasValue ? blobOffset.Value : 0), bufferSize - bufferOffset); - if (length.HasValue && (length.Value < downloadSize)) - { - downloadSize = (int)length.Value; - } - - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < bufferOffset; i++) - { - Assert.AreEqual(0, resultBuffer[i]); - } - - for (int j = 0; j < downloadLength; j++) - { - Assert.AreEqual(buffer[(blobOffset.HasValue ? blobOffset.Value : 0) + j], resultBuffer[bufferOffset + j]); - } - - for (int k = bufferOffset + downloadLength; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer[k]); - } - } - } - - #region Negative tests - [TestMethod] - // [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayNegativeTestsAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayNegativeTestsAsync(blob); - } - - [TestMethod] - // [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayNegativeTestsAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayNegativeTestsAsync(blob); - } - - private async Task DoDownloadRangeToByteArrayNegativeTestsAsync(ICloudBlob blob) - { - int blobLength = 1024; - int resultBufSize = 1024; - byte[] buffer = GetRandomBuffer(blobLength); - byte[] resultBuffer = new byte[resultBufSize]; - - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(stream.AsInputStream()); - - OperationContext context = new OperationContext(); - await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, 1024, 1, null, null, context), context, "Try invalid length", HttpStatusCode.RequestedRangeNotSatisfiable); - WrappedStorageException ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadToByteArrayAsync(resultBuffer, 1024), "Provide invalid offset"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(NotSupportedException)); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 1023, 0, 2), "Should fail when offset + length required is greater than size of the buffer"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(NotSupportedException)); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, 0, -10), "Fail when a negative length is specified"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(ArgumentOutOfRangeException)); - await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, -10, 0, 20), "Fail if a negative offset is provided"); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, -10, 20), "Fail if a negative blob offset is provided"); - Assert.IsInstanceOfType(ex.InnerException.InnerException, typeof(ArgumentOutOfRangeException)); - } - } - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobWriteStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobWriteStreamTest.cs deleted file mode 100644 index f627bcf083e10..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/BlobWriteStreamTest.cs +++ /dev/null @@ -1,713 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobWriteStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create blobs using blob stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobWriteStreamOpenAndCloseAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (IOutputStream writeStream = await blockBlob.OpenWriteAsync()) - { - } - - CloudBlockBlob blockBlob2 = container.GetBlockBlobReference("blob1"); - await blockBlob2.FetchAttributesAsync(); - Assert.AreEqual(0, blockBlob2.Properties.Length); - Assert.AreEqual(BlobType.BlockBlob, blockBlob2.Properties.BlobType); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await pageBlob.OpenWriteAsync(null, null, null, opContext), - opContext, - "Opening a page blob stream with no size should fail on a blob that does not exist", - HttpStatusCode.NotFound); - using (IOutputStream writeStream = await pageBlob.OpenWriteAsync(1024)) - { - } - using (IOutputStream writeStream = await pageBlob.OpenWriteAsync(null)) - { - } - - CloudPageBlob pageBlob2 = container.GetPageBlobReference("blob2"); - await pageBlob2.FetchAttributesAsync(); - Assert.AreEqual(1024, pageBlob2.Properties.Length); - Assert.AreEqual(BlobType.PageBlob, pageBlob2.Properties.BlobType); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamOpenWithAccessConditionAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - OperationContext context = new OperationContext(); - - CloudBlockBlob existingBlob = container.GetBlockBlobReference("blob"); - await existingBlob.PutBlockListAsync(new List()); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotFound); - - blob = container.GetBlockBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - IOutputStream blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await existingBlob.SetPropertiesAsync(); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetBlockBlobReference("blob7"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - await blob.PutBlockListAsync(new List()); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - blob = container.GetBlockBlobReference("blob8"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await existingBlob.SetPropertiesAsync(); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamOpenWithAccessConditionAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - OperationContext context = new OperationContext(); - - CloudPageBlob existingBlob = container.GetPageBlobReference("blob"); - await existingBlob.CreateAsync(1024); - - CloudPageBlob blob = container.GetPageBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetPageBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - IOutputStream blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.ParallelOperationThreadCount = 2; - string name = GetRandomContainerName(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - using (IOutputStream writeStream = await blob.OpenWriteAsync(null, options, null)) - { - Stream blobStream = writeStream.AsStreamForWrite(); - - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - hasher.Append(buffer.AsBuffer()); - } - - await blobStream.FlushAsync(); - } - - string md5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - await blob.FetchAttributesAsync(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - } - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamSeekTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (IOutputStream writeStream = await blob.OpenWriteAsync()) - { - Stream blobStream = writeStream.AsStreamForWrite(); - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Block blob write stream should not be seekable"); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamFlushTestAsync() - { - byte[] buffer = GetRandomBuffer(512 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - OperationContext opContext = new OperationContext(); - using (ICloudBlobStream blobStream = await blob.OpenWriteAsync(null, null, opContext)) - { - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer.AsBuffer()); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - } - - Assert.AreEqual(1, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.WriteAsync(buffer.AsBuffer()); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.CommitAsync(); - - Assert.AreEqual(4, opContext.RequestResults.Count); - } - - Assert.AreEqual(4, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob.AsOutputStream()); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(6 * 512); - - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 8 * 512; - - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - using (IOutputStream writeStream = await blob.OpenWriteAsync(buffer.Length * 3, null, options, null)) - { - Stream blobStream = writeStream.AsStreamForWrite(); - - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - hasher.Append(buffer.AsBuffer()); - } - - await blobStream.FlushAsync(); - } - - string md5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - await blob.FetchAttributesAsync(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenWriteAsync(null, null, options, null), - "OpenWrite with StoreBlobContentMD5 on an existing page blob should fail"); - - using (IOutputStream writeStream = await blob.OpenWriteAsync(null)) - { - Stream blobStream = writeStream.AsStreamForWrite(); - blobStream.Seek(buffer.Length / 2, SeekOrigin.Begin); - wholeBlob.Seek(buffer.Length / 2, SeekOrigin.Begin); - - for (int i = 0; i < 2; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - await blobStream.FlushAsync(); - } - - await blob.FetchAttributesAsync(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - options.DisableContentMD5Validation = true; - await blob.DownloadToStreamAsync(downloadedBlob, null, options, null); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - } - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamRandomSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - using (IOutputStream writeStream = await blob.OpenWriteAsync(buffer.Length)) - { - Stream blobStream = writeStream.AsStreamForWrite(); - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Page blob stream should not allow unaligned seeks"); - - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Random random = new Random(); - for (int i = 0; i < 10; i++) - { - int offset = random.Next(buffer.Length / 512) * 512; - SeekRandomly(blobStream, offset); - await blobStream.WriteAsync(buffer, 0, buffer.Length - offset); - wholeBlob.Seek(offset, SeekOrigin.Begin); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length - offset); - } - } - - await blob.FetchAttributesAsync(); - Assert.IsNull(blob.Properties.ContentMD5); - - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamFlushTestAsync() - { - byte[] buffer = GetRandomBuffer(512); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() { StoreBlobContentMD5 = true }; - OperationContext opContext = new OperationContext(); - using (ICloudBlobStream blobStream = await blob.OpenWriteAsync(4 * 512, null, options, opContext)) - { - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer.AsBuffer()); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - } - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await blobStream.WriteAsync(buffer.AsBuffer()); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await blobStream.CommitAsync(); - - Assert.AreEqual(5, opContext.RequestResults.Count); - } - - Assert.AreEqual(5, opContext.RequestResults.Count); - - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobClientTest.cs deleted file mode 100644 index 3212597165926..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobClientTest.cs +++ /dev/null @@ -1,455 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobClientTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientConstructor() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - Assert.IsTrue(blobClient.BaseUri.ToString().Contains(TestBase.TargetTenantConfig.BlobServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, blobClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, blobClient.AuthenticationScheme); - } - - [TestMethod] - /// [Description("Create a service client with uppercase account name")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientWithUppercaseAccountNameAsync() - { - StorageCredentials credentials = new StorageCredentials(TestBase.StorageCredentials.AccountName.ToUpper(), Convert.ToBase64String(TestBase.StorageCredentials.ExportKey())); - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient blobClient = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - await container.ExistsAsync(); - } - - [TestMethod] - /// [Description("Compare service client properties of blob objects")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientObjects() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - Assert.AreEqual(blobClient, container.ServiceClient); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blockblob"); - Assert.AreEqual(blobClient, blockBlob.ServiceClient); - CloudPageBlob pageBlob = container.GetPageBlobReference("pageblob"); - Assert.AreEqual(blobClient, pageBlob.ServiceClient); - - CloudBlobContainer container2 = GetRandomContainerReference(); - Assert.AreNotEqual(blobClient, container2.ServiceClient); - CloudBlockBlob blockBlob2 = container2.GetBlockBlobReference("blockblob"); - Assert.AreEqual(container2.ServiceClient, blockBlob2.ServiceClient); - CloudPageBlob pageBlob2 = container2.GetPageBlobReference("pageblob"); - Assert.AreEqual(container2.ServiceClient, pageBlob2.ServiceClient); - } - - [TestMethod] - /// [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListBlobsSegmentedWithPrefixAsync() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - await rootContainer.CreateIfNotExistsAsync(); - await container.CreateAsync(); - - List blobNames = await CreateBlobsAsync(container, 3, BlobType.BlockBlob); - List rootBlobNames = await CreateBlobsAsync(rootContainer, 2, BlobType.BlockBlob); - - BlobResultSegment results; - BlobContinuationToken token = null; - do - { - results = await blobClient.ListBlobsSegmentedAsync("bb", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - await blob.DeleteAsync(); - rootBlobNames.Remove(blob.Name); - } - } - while (token != null); - Assert.AreEqual(0, rootBlobNames.Count); - - results = await blobClient.ListBlobsSegmentedAsync("bb", token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - results = await blobClient.ListBlobsSegmentedAsync(name, token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - token = null; - do - { - results = await blobClient.ListBlobsSegmentedAsync(name + "/", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("List containers")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListContainersSegmentedAsync() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - await blobClient.GetContainerReference(containerName).CreateAsync(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = await blobClient.ListContainersSegmentedAsync(token); - token = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - foreach (string containerName in listedContainerNames) - { - if (containerNames.Remove(containerName)) - { - await blobClient.GetContainerReference(containerName).DeleteAsync(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - /// [Description("List containers with prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListContainersSegmentedWithPrefixAsync() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - await blobClient.GetContainerReference(containerName).CreateAsync(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = await blobClient.ListContainersSegmentedAsync(name, ContainerListingDetails.None, 1, token, null, null); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - Assert.IsTrue(count <= 1); - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - await blobClient.GetContainerReference(containerName).DeleteAsync(); - } - } - - [TestMethod] - // [Description("Test Create Container with Shared Key Lite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientCreateContainerSharedKeyLiteAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string containerName = GetRandomContainerName(); - CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName); - await blobContainer.CreateAsync(); - - bool exists = await blobContainer.ExistsAsync(); - Assert.IsTrue(exists); - - await blobContainer.DeleteAsync(); - } - - [TestMethod] - /// [Description("Upload a blob with a small maximum execution time")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientMaximumExecutionTimeoutAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(20 * 1024 * 1024); - - try - { - await container.CreateAsync(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(5); - - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - await blockBlob.UploadFromStreamAsync(ms.AsInputStream()); - } - catch (Exception ex) - { - Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.Message).ExceptionInfo.Message); - } - } - - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - await pageBlob.UploadFromStreamAsync(ms.AsInputStream()); - } - catch (AggregateException ex) - { - Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.InnerException.InnerException.Message).ExceptionInfo.Message); - } - } - } - - finally - { - blobClient.MaximumExecutionTime = null; - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Make sure MaxExecutionTime is not enforced when using streams")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientMaximumExecutionTimeoutShouldNotBeHonoredForStreamsAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(1024 * 1024); - - try - { - await container.CreateAsync(); - - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(30); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - blockBlob.StreamWriteSizeInBytes = 1024 * 1024; - blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - pageBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - - using (ICloudBlobStream bos = await blockBlob.OpenWriteAsync()) - { - DateTime start = DateTime.Now; - for (int i = 0; i < 7; i++) - { - await bos.WriteAsync(buffer.AsBuffer()); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - await bos.WriteAsync(buffer.AsBuffer()); - await bos.CommitAsync(); - } - - using (Stream bis = (await blockBlob.OpenReadAsync()).AsStreamForRead()) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += await bis.ReadAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - while (true) - { - int count = await bis.ReadAsync(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - - using (ICloudBlobStream bos = await pageBlob.OpenWriteAsync(8 * 1024 * 1024)) - { - DateTime start = DateTime.Now; - for (int i = 0; i < 7; i++) - { - await bos.WriteAsync(buffer.AsBuffer()); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - await bos.WriteAsync(buffer.AsBuffer()); - await bos.CommitAsync(); - } - - using (Stream bis = (await pageBlob.OpenReadAsync()).AsStreamForRead()) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += await bis.ReadAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - while (true) - { - int count = await bis.ReadAsync(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - } - - finally - { - blobClient.MaximumExecutionTime = null; - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobContainerTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobContainerTest.cs deleted file mode 100644 index 01018221ceeae..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobContainerTest.cs +++ /dev/null @@ -1,633 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; -using Windows.Globalization; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobContainerTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - private static async Task TestAccessAsync(BlobContainerPublicAccessType accessType, CloudBlobContainer container, ICloudBlob inputBlob) - { - StorageCredentials credentials = new StorageCredentials(); - container = new CloudBlobContainer(container.Uri, credentials); - CloudPageBlob blob = new CloudPageBlob(inputBlob.Uri, credentials); - OperationContext context = new OperationContext(); - BlobRequestOptions options = new BlobRequestOptions(); - - if (accessType.Equals(BlobContainerPublicAccessType.Container)) - { - await blob.FetchAttributesAsync(); - await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context); - await container.FetchAttributesAsync(); - } - else if (accessType.Equals(BlobContainerPublicAccessType.Blob)) - { - await blob.FetchAttributesAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context), - context, - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.FetchAttributesAsync(null, options, context), - context, - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.FetchAttributesAsync(null, options, context), - context, - "Fetch blob attributes while public access does not allow", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context), - context, - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.FetchAttributesAsync(null, options, context), - context, - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - } - - [TestMethod] - // [Description("Validate container references")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerReference() - { - CloudBlobClient client = GenerateCloudBlobClient(); - CloudBlobContainer container = client.GetContainerReference("container"); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("directory1/blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("directory2/blob2"); - CloudBlobDirectory directory = container.GetDirectoryReference("directory3"); - CloudBlobDirectory directory2 = directory.GetSubdirectoryReference("directory4"); - - Assert.AreEqual(container, blockBlob.Container); - Assert.AreEqual(container, pageBlob.Container); - Assert.AreEqual(container, directory.Container); - Assert.AreEqual(container, directory2.Container); - Assert.AreEqual(container, directory2.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - } - - [TestMethod] - /// [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - OperationContext operationContext = new OperationContext(); - Assert.ThrowsException( - () => container.CreateAsync(null, operationContext).AsTask().Wait(), - "Creating already exists container should fail"); - Assert.AreEqual((int)HttpStatusCode.Conflict, operationContext.LastResult.HttpStatusCode); - await container.DeleteAsync(); - } - - [TestMethod] - /// [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateIfNotExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(await container.CreateIfNotExistsAsync()); - Assert.IsFalse(await container.CreateIfNotExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try to delete a non-existing container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - Assert.IsFalse(await container.DeleteIfExistsAsync()); - await container.CreateAsync(); - Assert.IsTrue(await container.DeleteIfExistsAsync()); - Assert.IsFalse(await container.DeleteIfExistsAsync()); - } - - [TestMethod] - // [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithContainerAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Container, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Container, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Container, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithBlobAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Blob, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Blob, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Blob, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithPrivateAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Off, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Off, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Off, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Check a container's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - - try - { - Assert.IsFalse(await container2.ExistsAsync()); - - await container.CreateAsync(); - - Assert.IsTrue(await container2.ExistsAsync()); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - - Assert.IsFalse(await container2.ExistsAsync()); - } - - [TestMethod] - /// [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSetPermissionsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - BlobContainerPermissions permissions = await container.GetPermissionsAsync(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - await container.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = await container2.GetPermissionsAsync(); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("key1", "value1"); - await container.CreateAsync(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - await container2.FetchAttributesAsync(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - Assert.IsTrue(container2.Properties.LastModified.Value.AddHours(1) > DateTimeOffset.Now); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - await container2.FetchAttributesAsync(); - Assert.AreEqual(0, container2.Metadata.Count); - - container.Metadata.Add("key1", "value1"); - await container.SetMetadataAsync(); - - await container2.FetchAttributesAsync(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - ContainerResultSegment results = await container.ServiceClient.ListContainersSegmentedAsync(container.Name, ContainerListingDetails.Metadata, null, null, null, null); - CloudBlobContainer container3 = results.Results.First(); - Assert.AreEqual(1, container3.Metadata.Count); - Assert.AreEqual("value1", container3.Metadata["key1"]); - - container.Metadata.Clear(); - await container.SetMetadataAsync(); - - await container2.FetchAttributesAsync(); - Assert.AreEqual(0, container2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerRegionalSetMetadataAsync() - { - string currentPrimaryLanguage = ApplicationLanguages.PrimaryLanguageOverride; - ApplicationLanguages.PrimaryLanguageOverride = "sk-SK"; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("sequence", "value"); - container.Metadata.Add("schema", "value"); - await container.CreateAsync(); - } - finally - { - ApplicationLanguages.PrimaryLanguageOverride = currentPrimaryLanguage; - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerListBlobsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - List blobNames = await CreateBlobsAsync(container, 3, BlobType.PageBlob); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - Assert.AreEqual(blobNames.Count, results.Results.Count()); - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerListBlobsSegmentedAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - List blobNames = await CreateBlobsAsync(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, 1, token, null, null); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.AreEqual(1, count); - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerGetBlobReferenceFromServerAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - Permissions = SharedAccessBlobPermissions.Read, - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - }; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("bb"); - await blockBlob.PutBlockListAsync(new List()); - - CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); - await pageBlob.CreateAsync(0); - - ICloudBlob blob1 = await container.GetBlobReferenceFromServerAsync("bb"); - Assert.IsInstanceOfType(blob1, typeof(CloudBlockBlob)); - - CloudBlockBlob blob1Snapshot = await ((CloudBlockBlob)blob1).CreateSnapshotAsync(); - await blob1.SetPropertiesAsync(); - Uri blob1SnapshotUri = new Uri(blob1Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob1Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob1SnapshotReference = await container.ServiceClient.GetBlobReferenceFromServerAsync(blob1SnapshotUri); - AssertAreEqual(blob1Snapshot.Properties, blob1SnapshotReference.Properties); - - ICloudBlob blob2 = await container.GetBlobReferenceFromServerAsync("pb"); - Assert.IsInstanceOfType(blob2, typeof(CloudPageBlob)); - - CloudPageBlob blob2Snapshot = await ((CloudPageBlob)blob2).CreateSnapshotAsync(); - await blob2.SetPropertiesAsync(); - Uri blob2SnapshotUri = new Uri(blob2Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob2Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob2SnapshotReference = await container.ServiceClient.GetBlobReferenceFromServerAsync(blob2SnapshotUri); - AssertAreEqual(blob2Snapshot.Properties, blob2SnapshotReference.Properties); - - ICloudBlob blob3 = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlob.Uri); - Assert.IsInstanceOfType(blob3, typeof(CloudBlockBlob)); - - ICloudBlob blob4 = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlob.Uri); - Assert.IsInstanceOfType(blob4, typeof(CloudPageBlob)); - - string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); - StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); - Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); - - string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); - StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); - Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); - - ICloudBlob blob5 = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSASUri); - Assert.IsInstanceOfType(blob5, typeof(CloudBlockBlob)); - - ICloudBlob blob6 = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSASUri); - Assert.IsInstanceOfType(blob6, typeof(CloudPageBlob)); - - CloudBlobClient client7 = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); - ICloudBlob blob7 = await client7.GetBlobReferenceFromServerAsync(blockBlobSASUri); - Assert.IsInstanceOfType(blob7, typeof(CloudBlockBlob)); - - CloudBlobClient client8 = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); - ICloudBlob blob8 = await client8.GetBlobReferenceFromServerAsync(pageBlobSASUri); - Assert.IsInstanceOfType(blob8, typeof(CloudPageBlob)); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test conditional access on a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - await container.FetchAttributesAsync(); - - string currentETag = container.Properties.ETag; - DateTimeOffset currentModifiedTime = container.Properties.LastModified.Value; - - // ETag conditional tests - container.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await container.SetMetadataAsync(); - - await container.FetchAttributesAsync(); - string newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - // LastModifiedTime tests - currentModifiedTime = container.Properties.LastModified.Value; - - container.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - container.Metadata["DateConditionalName"] = "DateConditionalValue2"; - currentETag = container.Properties.ETag; - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - await container.FetchAttributesAsync(); - newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobDirectoryTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobDirectoryTest.cs deleted file mode 100644 index a6efe9ae0c21c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlobDirectoryTest.cs +++ /dev/null @@ -1,491 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Threading.Tasks; - - [TestClass] - public class CloudBlobDirectoryTest : BlobTestBase - { - string[] Delimiters = new string[] { "$", "@", "-", "%", "/", "|"}; - - private async Task CloudBlobDirectorySetupWithDelimiterAsync(CloudBlobContainer container, string delimiter = "/") - { - try - { - for (int i = 1; i < 3; i++) - { - for (int j = 1; j < 3; j++) - { - for (int k = 1; k < 3; k++) - { - String directory = "TopDir" + i + delimiter + "MidDir" + j + delimiter + "EndDir" + k + delimiter + "EndBlob" + k; - CloudPageBlob blob1 = container.GetPageBlobReference(directory); - await blob1.CreateAsync(0); - } - } - - CloudPageBlob blob2 = container.GetPageBlobReference("TopDir" + i + delimiter + "Blob" + i); - await blob2.CreateAsync(0); - } - - return true; - } - catch (Exception e) - { - throw e; - } - - } - - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("CloudBlobDirectory Get parent")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryGetParentAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.ExistsAsync()); - Assert.AreEqual("Dir1" + delimiter + "Blob1", blob.Name); - CloudBlobDirectory parent = blob.Parent; - Assert.AreEqual(parent.Prefix, "Dir1" + delimiter); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - } - - [TestMethod] - /// [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryFlatListingAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - await container.CreateAsync(); - if (await CloudBlobDirectorySetupWithDelimiterAsync(container, delimiter)) - { - BlobResultSegment segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.None, null, null, null, null); - List simpleList1 = new List(); - simpleList1.AddRange(segment.Results); - while (segment.ContinuationToken != null) - { - segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.None, null, segment.ContinuationToken, null, null); - simpleList1.AddRange(segment.Results); - } - - Assert.IsTrue(simpleList1.Count == 3); - IListBlobItem item11 = simpleList1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - BlobResultSegment segment2 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1", true, BlobListingDetails.None, null, null, null, null); - List simpleList2 = new List(); - simpleList2.AddRange(segment2.Results); - while (segment2.ContinuationToken != null) - { - segment2 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1", true, BlobListingDetails.None, null, segment2.ContinuationToken, null, null); - simpleList2.AddRange(segment2.Results); - } - - Assert.IsTrue(simpleList2.Count == 2); - - IListBlobItem item21 = simpleList2.ElementAt(0); - Assert.IsTrue(item21.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item22 = simpleList2.ElementAt(1); - Assert.IsTrue(item22.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - - BlobResultSegment segment3 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1"+delimiter, false, BlobListingDetails.None, null, null, null, null); - List simpleList3 = new List(); - simpleList3.AddRange(segment3.Results); - while (segment3.ContinuationToken != null) - { - segment3 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1" + delimiter, false, BlobListingDetails.None, null, segment3.ContinuationToken, null, null); - simpleList3.AddRange(segment3.Results); - } - Assert.IsTrue(simpleList3.Count == 2); - - IListBlobItem item31 = simpleList3.ElementAt(0); - Assert.IsTrue(item31.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter)); - - IListBlobItem item32 = simpleList3.ElementAt(1); - Assert.IsTrue(item32.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter)); - - BlobResultSegment segment4 = await midDir2.ListBlobsSegmentedAsync(true, BlobListingDetails.None, null, null, null, null); - List simpleList4 = new List(); - simpleList4.AddRange(segment4.Results); - while (segment4.ContinuationToken != null) - { - segment4 = await midDir2.ListBlobsSegmentedAsync(true, BlobListingDetails.None, null, segment4.ContinuationToken, null, null); - simpleList4.AddRange(segment4.Results); - } - - Assert.IsTrue(simpleList4.Count == 2); - - IListBlobItem item41 = simpleList4.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = simpleList4.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Get subdirectory and then traverse back to parent")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetSubdirectoryAndTraverseBackToParentAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Get parent on root")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetParentOnRootAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - CloudBlobDirectory root = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory parent = root.Parent; - Assert.IsNull(parent); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Check multiple delimiters")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryMultipleDelimitersAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - ////Set the default delimiter to \ - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - await container.CreateAsync(); - try - { - if (await CloudBlobDirectorySetupWithDelimiterAsync(container, delimiter)) - { - BlobResultSegment segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.UncommittedBlobs, null, null, null, null); - List simpleList = new List(); - simpleList.AddRange(segment.Results); - while (segment.ContinuationToken != null) - { - segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.UncommittedBlobs, null, segment.ContinuationToken, null, null); - simpleList.AddRange(segment.Results); - } - - Assert.IsTrue(simpleList.Count == 3); - - IListBlobItem item11 = simpleList.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Hierarchical traversal")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryHierarchicalTraversalAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - ////Traverse hierarchically starting with length 1 - CloudBlobDirectory directory1 = container.GetDirectoryReference("Dir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("Dir2"); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("Dir3"); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - - CloudBlobDirectory subdir3 = subdir2.GetSubdirectoryReference("Dir4"); - CloudBlobDirectory parent3 = subdir3.Parent; - Assert.AreEqual(parent3.Prefix, subdir2.Prefix); - - CloudBlobDirectory subdir4 = subdir3.GetSubdirectoryReference("Dir5"); - CloudBlobDirectory parent4 = subdir4.Parent; - Assert.AreEqual(parent4.Prefix, subdir3.Prefix); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Get directory parent for blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryBlobParentValidateAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - CloudPageBlob blob = container.GetPageBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - [TestMethod] - /// [Description("Validate CloudBlobDirectory in root container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryValidateInRootContainerAsync() - { - foreach (String delimiter in Delimiters) - { - - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - CloudBlobContainer container = client.GetContainerReference("$root"); - - CloudPageBlob pageBlob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - OperationContext context = new OperationContext(); - if (delimiter == "/") - { - await TestHelper.ExpectedExceptionAsync( - async () => await pageBlob.CreateAsync(0, null, null, context), context, - "Try to create a CloudBlobDirectory/blob which has a slash in its name in the root container", - HttpStatusCode.BadRequest); - } - else - { - CloudPageBlob blob = container.GetPageBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - - CloudBlobDirectory directory1 = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("MidDir" + delimiter); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - Assert.AreEqual(parent1.Uri, directory1.Uri); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("EndDir" + delimiter); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - Assert.AreEqual(parent2.Uri, subdir1.Uri); - } - } - } - - [TestMethod] - /// [Description("Multiple delimiters in a row or empty directory names")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryDelimitersInARowAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudPageBlob blob = container.GetPageBlobReference(delimiter + delimiter + delimiter + "Blob1"); - - ////Traverse from leaf to root - CloudBlobDirectory directory1 = blob.Parent; - Assert.AreEqual(directory1.Prefix, delimiter + delimiter + delimiter); - - CloudBlobDirectory directory2 = directory1.Parent; - Assert.AreEqual(directory2.Prefix, delimiter + delimiter); - - CloudBlobDirectory directory3 = directory2.Parent; - Assert.AreEqual(directory3.Prefix, delimiter); - - ////Traverse from root to leaf - CloudBlobDirectory directory4 = container.GetDirectoryReference(delimiter); - CloudBlobDirectory directory5 = directory4.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory5.Prefix, delimiter + delimiter); - - CloudBlobDirectory directory6 = directory5.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory6.Prefix, delimiter + delimiter + delimiter); - - CloudPageBlob blob2 = directory6.GetPageBlobReference("Blob1"); - Assert.AreEqual(blob2.Name, delimiter + delimiter + delimiter + "Blob1"); - Assert.AreEqual(blob2.Uri, blob.Uri); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } - - - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlockBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlockBlobTest.cs deleted file mode 100644 index 0215f7a05c7f5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudBlockBlobTest.cs +++ /dev/null @@ -1,1431 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Text; -using System.Threading.Tasks; -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlockBlobTest : BlobTestBase - { - private static async Task CreateForTestAsync(CloudBlockBlob blob, int blockCount, int blockSize, bool commit = true) - { - byte[] buffer = GetRandomBuffer(blockSize); - List blocks = GetBlockIdList(blockCount); - - foreach (string block in blocks) - { - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, stream.AsInputStream(), null); - } - } - - if (commit) - { - await blob.PutBlockListAsync(blocks); - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create a zero-length block blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCreateAndDeleteAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 0, 0); - Assert.IsTrue(await blob.ExistsAsync()); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try to delete a non-existing block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - await CreateForTestAsync(blob, 0, 0); - Assert.IsTrue(await blob.DeleteIfExistsAsync()); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - - Assert.IsFalse(await blob2.ExistsAsync()); - - await CreateForTestAsync(blob, 2, 1024); - - Assert.IsTrue(await blob2.ExistsAsync()); - Assert.AreEqual(2048, blob2.Properties.Length); - - await blob.DeleteAsync(); - - Assert.IsFalse(await blob2.ExistsAsync()); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobFetchAttributesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - Assert.AreEqual(-1, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob.Properties.BlobType); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSetPropertiesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - await Task.Delay(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - await blob.SetPropertiesAsync(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudBlockBlob blob3 = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - await blob3.DownloadToStreamAsync(stream.AsOutputStream(), null, options, null); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - CloudBlockBlob blob4 = (CloudBlockBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try retrieving properties of a block blob using a page blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobFetchAttributesInvalidTypeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - Assert.ThrowsException( - () => blob2.FetchAttributesAsync(null, null, operationContext).AsTask().Wait(), - "Fetching attributes of a block blob using a page blob reference should fail"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify that creating a block blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - await CreateForTestAsync(blob, 0, 0); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify that a block blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 0, 0); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - - OperationContext operationContext = new OperationContext(); - blob.Metadata["key1"] = null; - - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).AsTask().Wait(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).AsTask().Wait(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null); - CloudBlockBlob blob3 = (CloudBlockBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload blocks and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadAsync() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - using (MemoryStream wholeBlob = new MemoryStream()) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream.AsInputStream(), null); - } - wholeBlob.Write(buffer, 0, buffer.Length); - } - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream.AsInputStream(), null); - } - } - - await blob.PutBlockListAsync(blocks); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - using (MemoryOutputStream downloadedBlob = new MemoryOutputStream()) - { - await blob2.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob.UnderlyingStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload a block blob and then verify the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadBlockListAsync() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream.AsInputStream(), null); - } - } - await blob.PutBlockListAsync(blocks); - - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream.AsInputStream(), null); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024 * blocks.Count, blob2.Properties.Length); - - IEnumerable blockList = await blob2.DownloadBlockListAsync(); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsTrue(blockItem.Committed); - Assert.IsTrue(blocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, blocks.Count); - - blockList = await blob2.DownloadBlockListAsync(BlockListingFilter.Uncommitted, null, null, null); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsFalse(blockItem.Committed); - Assert.IsTrue(extraBlocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, extraBlocks.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob with invalid options")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamInvalidOptionsAsync() - { - BlobRequestOptions options = new BlobRequestOptions() - { - UseTransactionalMD5 = true, - StoreBlobContentMD5 = false, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.UploadFromStreamAsync(stream.AsInputStream(), null, options, null), - "Single put blob with mismatching MD5 options should fail immediately"); - } - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamWithAccessConditionAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0, true); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - await blob.FetchAttributesAsync(); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0, true), - operationContext, - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0, true); - - blob = container.GetBlockBlobReference("blob3"); - await CreateForTestAsync(blob, 1, 1024); - await blob.FetchAttributesAsync(); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0, true), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0, true), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamWithNonSeekableStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, true, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, false, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, true, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, false, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamLengthSinglePutAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload 2MB of 5MB stream - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, true, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, true, 1024, true); - - // Exclude last byte - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, true, true, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, false, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, false, true, 1024, true); - - // Upload exact amount - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, true, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, true, true, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, false, true, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, false, true, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload 2MB of 5MB stream - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, false, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, false, 1024, true); - - // Exclude last byte - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, true, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, true, false, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, false, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, false, false, 1024, true); - - // Upload exact amount - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, true, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, true, false, 1024, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, false, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, false, false, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamInvalidLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, null, true, true, 0, false), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, null, true, true, 1024, false), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, null, false, true, 0, false), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, null, false, true, 1024, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload blob using multiple threads and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobParallelUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 8; - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 16 * 1024 * 1024, null, null, null, true, false, 0, true); - await this.CloudBlockBlobUploadFromStreamAsync(container, 16 * 1024 * 1024, null, null, null, true, false, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - private async Task CloudBlockBlobUploadFromStreamAsync(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, OperationContext operationContext, bool seekableSourceStream, bool allowSinglePut, int startOffset, bool testMd5) - { - byte[] buffer = GetRandomBuffer(size); - - string md5 = string.Empty; - if (testMd5) - { - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - hasher.Append(buffer.AsBuffer(startOffset, copyLength.HasValue ? (int)copyLength : buffer.Length - startOffset)); - md5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - } - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.ServiceClient.SingleBlobUploadThresholdInBytes = allowSinglePut ? buffer.Length : buffer.Length / 2; - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - - using (MemoryStream originalBlobStream = new MemoryStream()) - { - originalBlobStream.Write(buffer, startOffset, buffer.Length - startOffset); - - Stream sourceStream; - if (seekableSourceStream) - { - MemoryStream stream = new MemoryStream(buffer); - stream.Seek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - else - { - NonSeekableMemoryStream stream = new NonSeekableMemoryStream(buffer); - stream.ForceSeek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - - using (sourceStream) - { - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - if (copyLength.HasValue) - { - await blob.UploadFromStreamAsync(sourceStream.AsInputStream(), copyLength.Value, accessCondition, options, operationContext); - } - else - { - await blob.UploadFromStreamAsync(sourceStream.AsInputStream(), accessCondition, options, operationContext); - } - } - - if (testMd5) - { - await blob.FetchAttributesAsync(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - } - - using (MemoryOutputStream downloadedBlobStream = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlobStream); - Assert.AreEqual(copyLength ?? originalBlobStream.Length, downloadedBlobStream.UnderlyingStream.Length); - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlobStream, - downloadedBlobStream.UnderlyingStream, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlobStream.Length); - } - } - } - - [TestMethod] - /// [Description("Create snapshots of a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSnapshotAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await blob.UploadFromStreamAsync(originalData.AsInputStream()); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudBlockBlob snapshot1 = await blob.CreateSnapshotAsync(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudBlockBlob snapshot2 = await blob.CreateSnapshotAsync(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - await snapshot1.FetchAttributesAsync(); - await snapshot2.FetchAttributesAsync(); - await blob.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudBlockBlob snapshot1Clone = new CloudBlockBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - await snapshot1Clone.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudBlockBlob snapshotCopy = container.GetBlockBlobReference("blob2"); - await snapshotCopy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot1.Uri)); - await WaitForCopyAsync(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - await TestHelper.ExpectedExceptionAsync( - async () => await snapshot1.OpenWriteAsync(), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync()).AsStreamForRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - await blob.PutBlockListAsync(new List()); - await blob.FetchAttributesAsync(); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync()).AsStreamForRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSnapshotMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 2, 1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - await blob.SetMetadataAsync(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudBlockBlob snapshot = await blob.CreateSnapshotAsync(snapshotMetadata, null, null, null); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - await snapshot.FetchAttributesAsync(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 2, 1024); - await blob.FetchAttributesAsync(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(currentETag), null, null); - - await blob.FetchAttributesAsync(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(newETag), null, operationContext), - operationContext, - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(invalidETag), null, operationContext), - operationContext, - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Put block boundaries")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobPutBlockBoundariesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - string blockId = GetBlockIdList(1).First(); - - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[0]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockId, stream.AsInputStream(), null, null, null, operationContext), - operationContext, - "Trying to upload a block with zero bytes should fail", - HttpStatusCode.BadRequest); - } - - buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockId, stream.AsInputStream(), null); - } - - buffer = new byte[4 * 1024 * 1024]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockId, stream.AsInputStream(), null); - } - - buffer = new byte[4 * 1024 * 1024 + 1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockId, stream.AsInputStream(), null, null, null, operationContext), - operationContext, - "Trying to upload a block with more than 4MB should fail", - HttpStatusCode.RequestEntityTooLarge); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload blocks and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobPutBlockAsync() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - hasher.Append(buffer.AsBuffer()); - string contentMD5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - List blockList = GetBlockIdList(2); - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - memoryStream.Seek(0, SeekOrigin.Begin); - await blob.PutBlockAsync(blockList[0], memoryStream.AsInputStream(), contentMD5); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockList[1], memoryStream.AsInputStream(), contentMD5, null, null, opContext), - opContext, - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.PutBlockAsync(blockList[1], memoryStream.AsInputStream(), null); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - await blob.PutBlockListAsync(blockList); - - using (MemoryStream blobData = new MemoryStream()) - { - await blob.DownloadToStreamAsync(blobData.AsOutputStream()); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test block blob methods on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobMethodsOnPageBlobAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List blobs = await CreateBlobsAsync(container, 1, BlobType.PageBlob); - CloudBlockBlob blob = container.GetBlockBlobReference(blobs.First()); - List blockList = GetBlockIdList(1); - - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockList.First(), stream.AsInputStream(), null, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockListAsync(blockList, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadBlockListAsync(BlockListingFilter.Committed, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test block removal/addition/reordering in a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobBlockReorderingAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - List originalBlockIds = GetBlockIdList(10); - List blockIds = new List(originalBlockIds); - List blocks = new List(); - for (int i = 0; i < blockIds.Count; i++) - { - byte[] buffer = Encoding.UTF8.GetBytes(i.ToString()); - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockIds[i], stream.AsInputStream(), null); - } - blocks.Add(buffer); - } - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("0123456789", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(0); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("123456789", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(8); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("12345678", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(3); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("1235678", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[9])) - { - await blob.PutBlockAsync(originalBlockIds[9], stream.AsInputStream(), null); - } - blockIds.Insert(0, originalBlockIds[9]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("91235678", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[0])) - { - await blob.PutBlockAsync(originalBlockIds[0], stream.AsInputStream(), null); - } - blockIds.Add(originalBlockIds[0]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("912356780", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[4])) - { - await blob.PutBlockAsync(originalBlockIds[4], stream.AsInputStream(), null); - } - blockIds.Insert(2, originalBlockIds[4]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("9142356780", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.Insert(0, originalBlockIds[0]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("09142356780", await DownloadTextAsync(blob, Encoding.UTF8)); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadDownloadNoDataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.UploadFromStreamAsync(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream()); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadToStreamAsync(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream.AsOutputStream()); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("List committed and uncommitted blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobListUncommittedBlobsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List committedBlobs = new List(); - for (int i = 0; i < 3; i++) - { - string name = "cblob" + i.ToString(); - CloudBlockBlob committedBlob = container.GetBlockBlobReference(name); - await CreateForTestAsync(committedBlob, 2, 1024); - committedBlobs.Add(name); - } - - List uncommittedBlobs = new List(); - for (int i = 0; i < 5; i++) - { - string name = "ucblob" + i.ToString(); - CloudBlockBlob uncommittedBlob = container.GetBlockBlobReference(name); - await CreateForTestAsync(uncommittedBlob, 2, 1024, false); - uncommittedBlobs.Add(name); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.UncommittedBlobs, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - foreach (ICloudBlob blob in blobs) - { - if (committedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(2 * 1024, blob.Properties.Length); - } - else if (uncommittedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(0, blob.Properties.Length); - } - else - { - Assert.Fail("Blob is not found in either committed or uncommitted list"); - } - } - - Assert.AreEqual(0, committedBlobs.Count); - Assert.AreEqual(0, uncommittedBlobs.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload and download text")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadTextAsync() - { - await this.DoTextUploadDownloadAsync("test"); - await this.DoTextUploadDownloadAsync("char中文test"); - await this.DoTextUploadDownloadAsync(""); - } - - private async Task DoTextUploadDownloadAsync(string text) - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateIfNotExistsAsync(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - await blob.UploadTextAsync(text); - Assert.AreEqual(text, await blob.DownloadTextAsync()); - - OperationContext context = new OperationContext(); - await blob.UploadTextAsync(text, null, null, context); - Assert.AreEqual(1, context.RequestResults.Count); - await blob.DownloadTextAsync(null, null, context); - Assert.AreEqual(2, context.RequestResults.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudPageBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudPageBlobTest.cs deleted file mode 100644 index ce2c5082dcd2d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CloudPageBlobTest.cs +++ /dev/null @@ -1,1236 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudPageBlobTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create a zero-length page blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCreateAndDeleteAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.ExistsAsync()); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Resize a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobResizeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - await blob.CreateAsync(1024); - Assert.AreEqual(1024, blob.Properties.Length); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - blob2.Properties.ContentType = "text/plain"; - await blob2.SetPropertiesAsync(); - await blob.ResizeAsync(2048); - Assert.AreEqual(2048, blob.Properties.Length); - await blob.FetchAttributesAsync(); - Assert.AreEqual("text/plain", blob.Properties.ContentType); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(2048, blob2.Properties.Length); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Use sequence number conditions on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSequenceNumberAsync() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - await blob.CreateAsync(buffer.Length); - Assert.IsNull(blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, 5); - Assert.AreEqual(5, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 7); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 3); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, null); - Assert.AreEqual(8, blob.Properties.PageBlobSequenceNumber); - - WrappedStorageException e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, null), - "SetSequenceNumber with Update should require a value"); - Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(ArgumentNullException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, -1), - "Negative sequence numbers are not supported"); - Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(ArgumentOutOfRangeException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, null), - "SetSequenceNumber with Max should require a value"); - Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(ArgumentNullException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, 1), - "SetSequenceNumber with Increment should require null value"); - Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(ArgumentException)); - - using (MemoryStream stream = new MemoryStream(buffer)) - { - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - OperationContext context = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream.AsInputStream(), AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream.AsInputStream(), AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream.AsInputStream(), AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try to delete a non-existing page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.DeleteIfExistsAsync()); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - Assert.IsFalse(await blob2.ExistsAsync()); - - await blob.CreateAsync(2048); - - Assert.IsTrue(await blob2.ExistsAsync()); - Assert.AreEqual(2048, blob2.Properties.Length); - - await blob.DeleteAsync(); - - Assert.IsFalse(await blob2.ExistsAsync()); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobFetchAttributesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - Assert.AreEqual(1024, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob.Properties.BlobType); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSetPropertiesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - await Task.Delay(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - await blob.SetPropertiesAsync(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudPageBlob blob3 = container.GetPageBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - await blob3.DownloadToStreamAsync(stream.AsOutputStream(), null, options, null); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - CloudPageBlob blob4 = (CloudPageBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try retrieving properties of a block blob using a page blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobFetchAttributesInvalidTypeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - Assert.ThrowsException( - () => blob2.FetchAttributesAsync(null, null, operationContext).AsTask().Wait(), - "Fetching attributes of a page blob using a block blob reference should fail"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify that creating a page blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - await blob.CreateAsync(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Verify that a page blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - - OperationContext operationContext = new OperationContext(); - blob.Metadata["key1"] = null; - - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).AsTask().Wait(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).AsTask().Wait(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null); - CloudPageBlob blob3 = (CloudPageBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload/clear pages in a page blob and then verify page ranges")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobGetPageRangesAsync() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(4 * 1024); - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.WritePagesAsync(memoryStream.AsInputStream(), 512, null); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.WritePagesAsync(memoryStream.AsInputStream(), 3 * 1024, null); - } - - await blob.ClearPagesAsync(1024, 1024); - await blob.ClearPagesAsync(0, 512); - - IEnumerable pageRanges = await blob.GetPageRangesAsync(); - List expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 4 * 1024 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - pageRanges = await blob.GetPageRangesAsync(1024, 1024, null, null, null); - Assert.AreEqual(0, pageRanges.Count()); - - pageRanges = await blob.GetPageRangesAsync(512, 3 * 1024, null, null, null); - expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 7 * 512 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.GetPageRangesAsync(1024, null, null, null, opContext), - opContext, - "Get Page Ranges with an offset but no count should fail", - HttpStatusCode.Unused); - Assert.IsInstanceOfType(opContext.LastResult.Exception.InnerException, typeof(ArgumentNullException)); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload pages to a page blob and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobWritePagesAsync() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - hasher.Append(buffer.AsBuffer()); - string contentMD5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(4 * 1024 * 1024); - - using (MemoryStream memoryStream = new MemoryStream()) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream.AsInputStream(), 0, null), - "Zero-length WritePages should fail"); - - memoryStream.SetLength(4 * 1024 * 1024 + 1); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream.AsInputStream(), 0, null), - ">4MB WritePages should fail"); - } - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream.AsInputStream(), 512, null, null, null, opContext), - opContext, - "Writing out-of-range pages should fail", - HttpStatusCode.RequestedRangeNotSatisfiable, - "InvalidPageRange"); - - memoryStream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream.AsInputStream(), 0, contentMD5); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream.AsInputStream(), 0, contentMD5, null, null, opContext), - opContext, - "Invalid MD5 should fail with mismatch", - HttpStatusCode.BadRequest, - "Md5Mismatch"); - - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream.AsInputStream(), 0, null); - resultingData.Seek(0, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - - offset = buffer.Length - 2048; - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream.AsInputStream(), 1024, null); - resultingData.Seek(1024, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - using (MemoryStream blobData = new MemoryStream()) - { - await blob.DownloadToStreamAsync(blobData.AsOutputStream()); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamWithAccessConditionAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0, true); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0, true), - operationContext, - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0, true); - - blob = container.GetPageBlobReference("blob3"); - await blob.CreateAsync(1024); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0, true), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, null, null, 0, true); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, null, null, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload half - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 0, true); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 1024, true); - - // Upload full stream - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 6 * 512, null, null, 0, true); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 4 * 512, null, null, 1024, true); - - // Exclude last page - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 5 * 512, null, null, 0, true); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 1024, true); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamLengthInvalidAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 3 * 512, 4 * 512, null, null, 0, false), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 3 * 512, 2 * 512, null, null, 1024, false), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.DeleteAsync().AsTask().Wait(); - } - } - - private async Task CloudPageBlobUploadFromStreamAsync(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, OperationContext operationContext, int startOffset, bool testMd5) - { - byte[] buffer = GetRandomBuffer(size); - - string md5 = string.Empty; - if (testMd5) - { - CryptographicHash hasher = HashAlgorithmProvider.OpenAlgorithm("MD5").CreateHash(); - hasher.Append(buffer.AsBuffer(startOffset, copyLength.HasValue ? (int)copyLength : buffer.Length - startOffset)); - md5 = CryptographicBuffer.EncodeToBase64String(hasher.GetValueAndReset()); - } - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 512; - - using (MemoryStream originalBlobStream = new MemoryStream()) - { - originalBlobStream.Write(buffer, startOffset, buffer.Length - startOffset); - - using (MemoryStream sourceStream = new MemoryStream(buffer)) - { - sourceStream.Seek(startOffset, SeekOrigin.Begin); - BlobRequestOptions options = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - if (copyLength.HasValue) - { - await blob.UploadFromStreamAsync(sourceStream.AsInputStream(), copyLength.Value, accessCondition, options, operationContext); - } - else - { - await blob.UploadFromStreamAsync(sourceStream.AsInputStream(), accessCondition, options, operationContext); - } - } - - if (testMd5) - { - await blob.FetchAttributesAsync(); - Assert.AreEqual(md5, blob.Properties.ContentMD5); - } - - using (MemoryOutputStream downloadedBlobStream = new MemoryOutputStream()) - { - await blob.DownloadToStreamAsync(downloadedBlobStream); - Assert.AreEqual(copyLength ?? originalBlobStream.Length, downloadedBlobStream.UnderlyingStream.Length); - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlobStream, - downloadedBlobStream.UnderlyingStream, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlobStream.Length); - } - } - } - - [TestMethod] - /// [Description("Create snapshots of a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSnapshotAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.UploadFromStreamAsync(originalData.AsInputStream()); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudPageBlob snapshot1 = await blob.CreateSnapshotAsync(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudPageBlob snapshot2 = await blob.CreateSnapshotAsync(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - await snapshot1.FetchAttributesAsync(); - await snapshot2.FetchAttributesAsync(); - await blob.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudPageBlob snapshot1Clone = new CloudPageBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - await snapshot1Clone.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudPageBlob snapshotCopy = container.GetPageBlobReference("blob2"); - await snapshotCopy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot1.Uri)); - await WaitForCopyAsync(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - await TestHelper.ExpectedExceptionAsync( - async () => await snapshot1.OpenWriteAsync(1024), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync()).AsStreamForRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - await blob.CreateAsync(1024); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync()).AsStreamForRead()) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSnapshotMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - await blob.SetMetadataAsync(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudPageBlob snapshot = await blob.CreateSnapshotAsync(snapshotMetadata, null, null, null); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - await snapshot.FetchAttributesAsync(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - await blob.FetchAttributesAsync(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(currentETag), null, null); - - await blob.FetchAttributesAsync(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(newETag), null, operationContext), - operationContext, - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(invalidETag), null, operationContext), - operationContext, - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test page blob methods on a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobMethodsOnBlockBlobAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List blobs = await CreateBlobsAsync(container, 1, BlobType.BlockBlob); - CloudPageBlob blob = container.GetPageBlobReference(blobs.First()); - - OperationContext operationContext = new OperationContext(); - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, 512, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.GetPageRangesAsync(null /* offset */, null /* length */, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test 512-byte page alignment")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobAlignmentAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.CreateAsync(511, null, null, operationContext), - operationContext, - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.CreateAsync(513, null, null, operationContext), - operationContext, - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - await blob.CreateAsync(512); - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(511); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, null, null, operationContext), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(513); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream.AsInputStream(), 0, null, null, null, operationContext), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - await blob.WritePagesAsync(stream.AsInputStream(), 0, null); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadDownloadNoDataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.UploadFromStreamAsync(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream()); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadToStreamAsync(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream.AsOutputStream()); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CopyBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CopyBlobTest.cs deleted file mode 100644 index 5f0bbee5e89b3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/CopyBlobTest.cs +++ /dev/null @@ -1,468 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CopyBlobTest : BlobTestBase - { - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - // [Description("CopyFromBlob with Unicode source blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CopyBlobUsingUnicodeBlobNameAsync() - { - string _unicodeBlobName = "繁体字14a6c"; - string _nonUnicodeBlobName = "sample_file"; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudBlockBlob blobUnicodeSource = container.GetBlockBlobReference(_unicodeBlobName); - string data = "Test content"; - await UploadTextAsync(blobUnicodeSource, data, Encoding.UTF8); - CloudBlockBlob blobAsciiSource = container.GetBlockBlobReference(_nonUnicodeBlobName); - await UploadTextAsync(blobAsciiSource, data, Encoding.UTF8); - - //Copy blobs over - CloudBlockBlob blobAsciiDest = container.GetBlockBlobReference(_nonUnicodeBlobName + "_copy"); - string copyId = await blobAsciiDest.StartCopyFromBlobAsync(TestHelper.Defiddler(blobAsciiSource)); - await WaitForCopyAsync(blobAsciiDest); - - CloudBlockBlob blobUnicodeDest = container.GetBlockBlobReference(_unicodeBlobName + "_copy"); - copyId = await blobUnicodeDest.StartCopyFromBlobAsync(TestHelper.Defiddler(blobUnicodeSource)); - await WaitForCopyAsync(blobUnicodeDest); - - Assert.AreEqual(CopyStatus.Success, blobUnicodeDest.CopyState.Status); - Assert.AreEqual(blobUnicodeSource.Uri.AbsolutePath, blobUnicodeDest.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.TotalBytes); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.BytesCopied); - Assert.AreEqual(copyId, blobUnicodeDest.CopyState.CopyId); - Assert.IsTrue(blobUnicodeDest.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await copy.AbortCopyAsync(copyId, null, null, opContext), - opContext, - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - await source.FetchAttributesAsync(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyTestWithMetadataOverrideAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - await source.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyFromSnapshotTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob snapshot = await source.CreateSnapshotAsync(); - - //Modify source - string newData = "Hello"; - source.Metadata["Test"] = "newvalue"; - await source.SetMetadataAsync(); - source.Properties.ContentMD5 = null; - await UploadTextAsync(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, await DownloadTextAsync(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, await DownloadTextAsync(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - await source.FetchAttributesAsync(); - await snapshot.FetchAttributesAsync(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, await DownloadTextAsync(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await copy.AbortCopyAsync(copyId, null, null, opContext), - opContext, - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - await source.FetchAttributesAsync(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyTestWithMetadataOverrideAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - await source.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyFromSnapshotTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob snapshot = await source.CreateSnapshotAsync(); - - //Modify source - string newData = new string('b', 512); - source.Metadata["Test"] = "newvalue"; - await source.SetMetadataAsync(); - source.Properties.ContentMD5 = null; - await UploadTextAsync(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, await DownloadTextAsync(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, await DownloadTextAsync(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - await source.FetchAttributesAsync(); - await snapshot.FetchAttributesAsync(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, await DownloadTextAsync(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/ExceptionHResultTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/ExceptionHResultTest.cs deleted file mode 100644 index 7c524126e5487..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/ExceptionHResultTest.cs +++ /dev/null @@ -1,160 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Core.Util; -using Microsoft.WindowsAzure.Storage.RetryPolicies; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class ExceptionHResultTest : TestBase - { - private readonly CloudBlobClient DefaultBlobClient = new CloudBlobClient(new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint), TestBase.StorageCredentials); - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudContainerCreateNegativeConflictAsync() - { - try - { - string name = "abc"; - CloudBlobContainer container = DefaultBlobClient.GetContainerReference(name); - await container.CreateAsync(); - await container.CreateAsync(); - Assert.Fail(); - } - catch (Exception e) - { - Assert.AreEqual(WindowsAzureErrorCode.HttpConflict, e.HResult); - } - } - - [TestMethod] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobUploadTimeoutAsync() - { - CloudBlobContainer container = DefaultBlobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(4 * 1024 * 1024); - - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - BlobRequestOptions requestOptions = new BlobRequestOptions() - { - MaximumExecutionTime = TimeSpan.FromSeconds(1), - RetryPolicy = new NoRetry() - }; - - using (MemoryStream ms = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(ms.AsInputStream(), null, requestOptions, null); - } - - Assert.Fail(); - } - catch (Exception e) - { - Assert.AreEqual(WindowsAzureErrorCode.TimeoutException, e.HResult); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobUploadCancellationAsync() - { - CloudBlobContainer container = DefaultBlobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(4 * 1024 * 1024); - - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - BlobRequestOptions requestOptions = new BlobRequestOptions() - { - RetryPolicy = new NoRetry() - }; - - CancellationTokenSource cts = new CancellationTokenSource(); - CancellationToken token = cts.Token; - - new Task(() => - { - new System.Threading.ManualResetEvent(false).WaitOne(500); - cts.Cancel(false); - }).Start(); - - using (MemoryStream ms = new MemoryStream(buffer)) - { - blob.UploadFromStreamAsync(ms.AsInputStream(), null, requestOptions, null).AsTask(token).Wait(); - } - - Assert.Fail(); - } - catch (AggregateException e) - { - TaskCanceledException ex = new TaskCanceledException(); - Assert.AreEqual(ex.HResult, e.InnerException.HResult); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/LeaseTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/LeaseTests.cs deleted file mode 100644 index 3f556559275eb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/LeaseTests.cs +++ /dev/null @@ -1,2926 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Blob.Protocol; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class LeaseTests : BlobTestBase - { - /// - /// The prefix to use for the current test. New containers and blobs in the root container begin with this prefix - /// to avoid conflicting with other tests or concurrent runs of the same test. This also allows a test to easily - /// clean itself up and to have a persistent recoverable state if a test fails. - /// - private string prefix; - - /// - /// The client for the blob service. - /// - private CloudBlobClient blobClient; - - /// - /// Create the given blob and, if necessary, its container. - /// - /// The blob to create. - internal static async Task CreateBlobAsync(ICloudBlob blob) - { - await blob.Container.CreateIfNotExistsAsync(); - await UploadTextAsync(blob, "LeaseTestBlobContent", Encoding.UTF8); - } - - /// - /// Get a reference to a container of the given name, prepending the current prefix. - /// - /// The name of the container to which the prefix will be prepended. - /// A reference to the container. - internal CloudBlobContainer GetContainerReference(string rootName) - { - return this.blobClient.GetContainerReference(string.Format("{0}-{1}", this.prefix, rootName)); - } - - [TestInitialize] - public void TestInitialize() - { - this.blobClient = GenerateCloudBlobClient(); - - // Create and log a new prefix for this test. - this.prefix = Guid.NewGuid().ToString("N"); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - // Retire this test's prefix. No other cleanup is done here. - this.prefix = null; - - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - /// - /// Deletes all containers beginning with the current prefix, and all blobs in the root container beginning with the current prefix. - /// Any existing lease is broken before the resource is deleted. All exceptions are ignored. - /// - internal async Task DeleteAllAsync() - { - try - { - // Delete all containers with prefix - ContainerResultSegment containers = await this.blobClient.ListContainersSegmentedAsync(this.prefix, ContainerListingDetails.None, null, null, null, null); - foreach (CloudBlobContainer container in containers.Results) - { - try - { - await container.BreakLeaseAsync(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - await container.DeleteAsync(); - } - catch (Exception) - { - } - } - - // Delete all blobs in root container with prefix - CloudBlobContainer rc = this.blobClient.GetRootContainerReference(); - BlobResultSegment blobs = await rc.ListBlobsSegmentedAsync(this.prefix, true, BlobListingDetails.None, null, null, null, null); - foreach (ICloudBlob blob in blobs.Results) - { - try - { - await blob.BreakLeaseAsync(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - await blob.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots, null /* access conditions */, null /* options */, null); - } - catch (Exception) - { - } - } - } - catch (Exception) - { - } - } - - /// - /// Puts the lease on the given blob in an available state. - /// - /// The blob with the lease. - internal static async Task SetAvailableStateAsync(ICloudBlob blob) - { - bool shouldBreakFirst = false; - - OperationContext operationContext = new OperationContext(); - try - { - await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.None, null, null, operationContext); - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - shouldBreakFirst = true; - } - else - { - throw; - } - } - - if (shouldBreakFirst) - { - await blob.BreakLeaseAsync(TimeSpan.Zero); - await blob.DeleteAsync(); - } - await CreateBlobAsync(blob); - } - - /// - /// Puts the lease on the given blob in a leased state. - /// - /// The blob with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static async Task SetLeasedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - await SetAvailableStateAsync(blob); - return await blob.AcquireLeaseAsync(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given blob in a renewed state. - /// - /// The blob with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static async Task SetRenewedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(blob, leaseTime); - await blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a released state. - /// - /// The blob with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static async Task SetReleasedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(blob, leaseTime); - await blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a breaking state for 60 seconds. - /// - /// The blob with the lease. - /// The lease ID of the current (but breaking) lease. - internal static async Task SetBreakingStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to the break period expiring. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static async Task SetTimeBrokenStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - await Task.Delay(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to a break period of zero. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static async Task SetInstantBrokenStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given blob in an expired state. - /// - /// The blob with the lease. - /// The lease ID of the expired lease. - internal static async Task SetExpiredStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, TimeSpan.FromSeconds(15)); - await Task.Delay(TimeSpan.FromSeconds(17)); - return leaseId; - } - - /// - /// Puts the lease on the given container in an unleased state (either available or broken). - /// - /// The container with the lease. - internal static async Task SetUnleasedStateAsync(CloudBlobContainer container) - { - if (!await container.CreateIfNotExistsAsync()) - { - OperationContext operationContext = new OperationContext(); - try - { - await container.BreakLeaseAsync(TimeSpan.Zero, null, null, operationContext); - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseAlreadyBroken || - operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation) - { - } - else - { - throw; - } - } - } - } - - /// - /// Puts the lease on the given container in a leased state. - /// - /// The container with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static async Task SetLeasedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - await SetUnleasedStateAsync(container); - return await container.AcquireLeaseAsync(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given container in a renewed state. - /// - /// The container with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static async Task SetRenewedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(container, leaseTime); - await container.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a released state. - /// - /// The container with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static async Task SetReleasedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(container, leaseTime); - await container.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a breaking state for 60 seconds. - /// - /// The container with the lease. - /// The lease ID of the current (but breaking) lease. - internal static async Task SetBreakingStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to the break period expiring. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static async Task SetTimeBrokenStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - await Task.Delay(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to a break period of zero. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static async Task SetInstantBrokenStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given container in an expired state. - /// - /// The container with the lease. - /// The lease ID of the expired lease. - internal static async Task SetExpiredStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, TimeSpan.FromSeconds(15)); - await Task.Delay(TimeSpan.FromSeconds(17)); - return leaseId; - } - - [TestMethod] - /// [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobAcquireLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await SetExpiredStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - await SetInstantBrokenStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobRenewLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(15)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await this.DeleteAllAsync(); - } - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. (This last feature is necessary for infinite leases.) - /// - /// The blob to test. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal async Task BlobAcquireRenewLeaseTestAsync(ICloudBlob leasedBlob, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - OperationContext operationContext = new OperationContext(); - DateTime beginTime = DateTime.UtcNow; - - bool testOver = false; - do - { - try - { - // Attempt to write to the blob with no lease ID. - await leasedBlob.SetMetadataAsync(null, null, operationContext); - - // The write succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Writes should not succeed while lease is present."); - - // Since the lease has expired, the test is over. - testOver = true; - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Writes should succeed after a lease expires."); - } - - // End the test early if necessary. - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - // Some other error occurred. Rethrow the exception. - throw; - } - } - - // Attempt to read from the blob. This should always succeed. - await leasedBlob.FetchAttributesAsync(); - - // Wait 1 second before trying again. - if (!testOver) - { - await Task.Delay(TimeSpan.FromSeconds(1)); - } - } - while (!testOver); - - // The lease expired. Write to and read from the blob once more. - await leasedBlob.SetMetadataAsync(); - await leasedBlob.FetchAttributesAsync(); - } - - [TestMethod] - /// [Description("Test blob leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeaseInvalidInputTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - await CreateBlobAsync(leasedBlob); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(1), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(14), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(61), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, invalidLeaseId, null, null, operationContext), - operationContext, - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the blob is leased - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(null /* access condition */, null, operationContext), - "renew with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateEmptyCondition(), null, operationContext), - "renew with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, null /* access condition */, null, operationContext), - "change with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateEmptyCondition(), null, operationContext), - "change with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - "change a lease with no proposed lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(null /* access condition */, null, operationContext), - "release with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateEmptyCondition(), null, operationContext), - "release with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(-1), null, null, operationContext), - "break with negative break time"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(61), null, null, operationContext), - operationContext, - "break with too large break time", - HttpStatusCode.BadRequest); - } - - [TestMethod] - /// [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobAcquireLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - leaseId2 = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId, null, null, operationContext), - operationContext, - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobRenewLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Renew lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = await SetExpiredStateAsync(leasedBlob); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = await SetExpiredStateAsync(leasedBlob); - string content = await DownloadTextAsync(leasedBlob, Encoding.UTF8); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = await SetExpiredStateAsync(leasedBlob); - await leasedBlob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = await SetReleasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = await SetReleasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobChangeLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Change lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, operationContext), - operationContext, - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobReleaseLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Release lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = await SetBreakingStateAsync(leasedBlob); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobBreakLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Break lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = await SetBreakingStateAsync(leasedBlob); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = await SetBreakingStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break finite lease (longer than lease time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break instant broken lease (default break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break instant broken lease (nonzero break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(null /* default break time */, null, null, operationContext), - operationContext, - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Tests blob write and delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeasedWriteTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob sourceBlob = leasedBlob.Container.GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // Verify that blob creation fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // BlobCreateExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create blob using a lease"); - - // From available state, verify that writes/deletes that pass a lease fail if none is present. - await SetAvailableStateAsync(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write blob using a lease when no lease is held"); - - // From leased state, verify that writes/deletes without a lease do not succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write blob using no lease when a lease is held"); - - // From leased state, verify that writes/deletes with the wrong lease fail. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write blob using a lease when a different lease is held"); - - // From leased state, verify that writes/deletes with the right lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - await this.BlobWriteExpectLeaseSuccessAsync(leasedBlob, sourceBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test blob write and creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobWriteExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - await this.BlobCreateExpectLeaseFailureAsync(testBlob, sourceBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.SetMetadataAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Properties)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test blob creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobCreateExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await UploadTextAsync(testBlob, "No Dice", Encoding.UTF8, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Upload Text)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.StartCopyFromBlobAsync(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Copy From)", - expectedStatusCode, - expectedErrorCode); - - IOutputStream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, operationContext); - Stream stream = writeStream.AsStreamForWrite(); - await TestHelper.ExpectedExceptionAsync( - async () => - { - stream.WriteByte(0); - await stream.FlushAsync(); - }, - operationContext, - description + " (Write Stream)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test blob writing, expecting success. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The access condition to use. - private async Task BlobWriteExpectLeaseSuccessAsync(CloudBlockBlob testBlob, ICloudBlob sourceBlob, AccessCondition testAccessCondition) - { - await testBlob.SetMetadataAsync(testAccessCondition, null /* options */, null); - await testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, null); - await UploadTextAsync(testBlob, "No Problem", Encoding.UTF8, testAccessCondition, null /* options */, null); - await testBlob.StartCopyFromBlobAsync(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, null); - - while (testBlob.CopyState.Status == CopyStatus.Pending) - { - await Task.Delay(1000); - await testBlob.FetchAttributesAsync(); - } - - IOutputStream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, null); - Stream stream = writeStream.AsStreamForWrite(); - stream.WriteByte(0); - await stream.FlushAsync(); - - await testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Tests blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeasedReadTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob targetBlob = leasedBlob.Container.GetBlockBlobReference("TargetBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // From available state, verify that reads that pass a lease fail if none is present - await SetAvailableStateAsync(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - await this.BlobReadExpectLeaseFailureAsync(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read blob using a lease when no lease is held"); - - // Verify that reads without a lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - await this.BlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - await this.BlobReadExpectLeaseFailureAsync(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - await this.BlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test blob reads, expecting lease failure. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobReadExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob targetBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Create Snapshot)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await DownloadTextAsync(testBlob, Encoding.UTF8, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Download Text)", - expectedStatusCode, - expectedErrorCode); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.OpenReadAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Read Stream)", - expectedStatusCode/*, - expectedErrorCode*/); - } - - /// - /// Test blob reads, expecting success. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The access condition to use. - private async Task BlobReadExpectLeaseSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, null); - await (await testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, null)).DeleteAsync(); - await DownloadTextAsync(testBlob, Encoding.UTF8, testAccessCondition, null /* options */, null); - - IRandomAccessStreamWithContentType readStream = await testBlob.OpenReadAsync(testAccessCondition, null /* options */, null); - Stream stream = readStream.AsStreamForRead(); - stream.ReadByte(); - } - - [TestMethod] - /// [Description("Tests page blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobLeasedWriteTestsAsync() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Verify that creating the page blob fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // PageBlobCreateExpectLeaseFailure(leasedBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create page blob using a lease"); - - // Create a page blob - testAccessCondition.LeaseId = null; - await PageBlobCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // From available state, verify that writing the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write page blob with no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write page blob using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await PageBlobWriteExpectSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test page blob creation, expecting lease failure. - /// - /// The page blob to test. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobCreateExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.CreateAsync(8 * 512, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Create Page Blob)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob writes, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobWriteExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - await PageBlobCreateExpectLeaseFailureAsync(testBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.ClearPagesAsync(512, 512, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Clear Pages)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.WritePagesAsync(pageStream.AsInputStream(), 512, null, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Write Pages)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob creation, expecting success. - /// - /// The page blob. - /// The test access condition. - private async Task PageBlobCreateExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.CreateAsync(8 * 512, testAccessCondition, null /* options */, null); - } - - /// - /// Test page blob writes, expecting success. - /// - /// The page blob. - /// The access condition to use. - private async Task PageBlobWriteExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - byte[] buffer = new byte[4 * 512]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - await testBlob.ClearPagesAsync(512, 512, testAccessCondition, null /* options */, null); - await testBlob.WritePagesAsync(pageStream.AsInputStream(), 512, null, testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Tests page blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobLeasedReadTestsAsync() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Create a page blob - testAccessCondition.LeaseId = null; - await PageBlobCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reading the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await PageBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease succeed. - testAccessCondition.LeaseId = null; - await PageBlobReadExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await PageBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read page blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await PageBlobReadExpectSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test page blob reads, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobReadExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.GetPageRangesAsync(null /* offset */, null /* length */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Get Page Ranges)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob reads, expecting success. - /// - /// The page blob. - /// The access condition to use. - private async Task PageBlobReadExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.GetPageRangesAsync(null /* offset */, null /* length */, testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Tests block blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedWriteTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - await leasedBlob.Container.CreateAsync(); - - // Verify that creating the first block fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testOptions.LeaseId = fakeLease; - // await BlockCreateExpectLeaseFailureAsync(leasedBlob, testOptions, BlobErrorCodeStrings.LeaseNotPresent, "create initial block using a lease"); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - - // Verify that creating an additional block fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "create additional block using a lease"); - - // Verify that block list writes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "set initial block list using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "set initial block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "set initial block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = null; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "update block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "update block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed, with the block list already set. - testAccessCondition.LeaseId = leaseId; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test block creation, expecting lease failure. - /// - /// The block blob in which to attempt to create a block. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockCreateExpectLeaseFailureAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await BlockCreateAsync(testBlob, testAccessCondition, operationContext), - operationContext, - description + " (Put Block)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob creation (block list setting), expecting lease failure. - /// - /// The block blob. - /// An appropriate block list to set. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockBlobWriteExpectLeaseFailureAsync(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.PutBlockListAsync(blockList, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Put Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block creation, expecting success. - /// - /// The block blob. - /// The test access condition. - /// The name of the new block. - private async Task BlockCreateExpectSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - return await BlockCreateAsync(testBlob, testAccessCondition, null); - } - - /// - /// Create a block with a random name. - /// - /// The block blob. - /// The access condition. - /// The name of the new block. - private async Task BlockCreateAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, OperationContext operationContext) - { - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - string blockId = Guid.NewGuid().ToString("N"); - Stream blockData = new MemoryStream(buffer); - await testBlob.PutBlockAsync(blockId, blockData.AsInputStream(), null /* content MD5 */, testAccessCondition, null /* options */, operationContext); - - return blockId; - } - - /// - /// Test block blob creation (set block list), expecting success. - /// - /// The block blob. - /// The block list to set. - /// The access condition to use. - private async Task BlockBlobWriteExpectSuccessAsync(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition) - { - await testBlob.PutBlockListAsync(blockList, testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Tests block blob read APIs in the presence of a lease on a blob with no block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedReadTestsWithoutListAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Create a block - testAccessCondition.LeaseId = null; - await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Tests block blob read APIs in the presence of a lease on a blob with a block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedReadTestsWithListAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - await leasedBlob.Container.CreateAsync(); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - - // Put the block list - testAccessCondition.LeaseId = null; - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test block blob reads, expecting lease failure. - /// - /// The block blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockBlobReadExpectLeaseFailureAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.DownloadBlockListAsync(BlockListingFilter.Committed, testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Download Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob reads, expecting success. - /// - /// The block blob. - /// The access condition to use. - private async Task BlockBlobReadExpectLeaseSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.DownloadBlockListAsync(BlockListingFilter.Committed, testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Test reading the blob lease status and state after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeaseStatusTestAsync() - { - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Check uninitialized lease status - await SetAvailableStateAsync(leasedBlob); - Assert.AreEqual(LeaseStatus.Unspecified, leasedBlob.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedBlob.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedBlob.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - await SetAvailableStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - await SetRenewedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - await SetRenewedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await leasedBlob.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - await SetBreakingStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - await SetTimeBrokenStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - await SetTimeBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /*proposed lease ID */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - await SetInstantBrokenStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - await SetExpiredStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - await this.DeleteAllAsync(); - } - - /// - /// Checks the lease status of a blob, both from its attributes and from a blob listing. - /// - /// The blob to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private async Task CheckLeaseStatusAsync( - ICloudBlob blob, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - await blob.FetchAttributesAsync(); - Assert.AreEqual(expectedStatus, blob.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, blob.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, blob.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - BlobResultSegment blobs = await blob.Container.ListBlobsSegmentedAsync(blob.Name, true, BlobListingDetails.None, null, null, null, null); - BlobProperties propertiesInListing = (from ICloudBlob b in blobs.Results - where b.Name == blob.Name - select b.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListBlobs)"); - } - - [TestMethod] - /// [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerAcquireLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-4"); // make sure we use a new container - await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-5"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-6"); // make sure we use a new container - await SetExpiredStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-7"); // make sure we use a new container - await SetInstantBrokenStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerRenewLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(15)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await this.DeleteAllAsync(); - } - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. - /// - /// The container. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal async Task ContainerAcquireRenewLeaseTestAsync(CloudBlobContainer leasedContainer, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - OperationContext operationContext = new OperationContext(); - DateTime beginTime = DateTime.UtcNow; - - while (true) - { - try - { - // Attempt to delete the container with no lease ID. - await leasedContainer.DeleteAsync(null, null, operationContext); - - // The delete succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Deletes should not succeed while lease is present."); - - // Since the lease has expired (and the container was deleted), the test is over. - return; - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Deletes should succeed after a lease expires."); - } - - // End the test early if necessary - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - throw; - } - } - - // Attempt to write to and read from the container. This should always succeed. - await leasedContainer.SetMetadataAsync(); - await leasedContainer.FetchAttributesAsync(); - - // Wait 1 second before trying again. - await Task.Delay(TimeSpan.FromSeconds(1)); - } - } - - [TestMethod] - /// [Description("Test container leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeaseInvalidInputTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - await leasedContainer.CreateAsync(); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(1), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(14), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(61), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, invalidLeaseId, null, null, operationContext), - operationContext, - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the container is leased - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(null /* access condition */), - "renew with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateEmptyCondition()), - "renew with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, null /* access condition */), - "change with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateEmptyCondition()), - "change with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with no proposed lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(null /* access condition */), - "release with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateEmptyCondition()), - "release with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(-1)), - "break with negative break time"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(61), null, null, operationContext), - operationContext, - "break with too large break time", - HttpStatusCode.BadRequest); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerAcquireLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Acquire the lease while in available state, make idempotent call - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - leaseId2 = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId, null, null, operationContext), - operationContext, - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerRenewLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Renew lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.FetchAttributesAsync(); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.SetMetadataAsync(); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = await SetReleasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = await SetReleasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerChangeLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Change lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, operationContext), - operationContext, - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerReleaseLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Release lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = await SetBreakingStateAsync(leasedContainer); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerBreakLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Break lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = await SetBreakingStateAsync(leasedContainer); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = await SetBreakingStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break finite lease (longer than lease time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break broken lease (default break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break instant broken lease (nonzero break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - /// [Description("Tests container delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeasedDeleteTestsAsync() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - - // Create the container - await leasedContainer.CreateAsync(); - - // Verify that deletes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "delete container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = await leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that deletes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "delete container using no lease when a lease is held"); - - // Verify that deletes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "delete container using a lease when a different lease is held"); - - // Verify that deletes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await this.ContainerDeleteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test container deletion, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task ContainerDeleteExpectLeaseFailureAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.DeleteAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container deletion, expecting success. - /// - /// The container. - /// The access condition to use. - private async Task ContainerDeleteExpectLeaseSuccessAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - await testContainer.DeleteAsync(testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Tests container read and write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeasedReadWriteTestsAsync() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - await leasedContainer.CreateAsync(); - - // Verify that reads and writes that pass a lease fail if none is present - testAccessCondition.LeaseId = fakeLease; - await this.ContainerReadWriteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "read/write container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = await leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads and writes without a lease succeed. - testAccessCondition.LeaseId = null; - await this.ContainerReadWriteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - // Verify that reads and writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerReadWriteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "read/write container using a lease when a different lease is held"); - - // Verify that reads and writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await this.ContainerReadWriteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test container reads and writes, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task ContainerReadWriteExpectLeaseFailureAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Get Permissions)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Permissions)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container reads and writes, expecting success. - /// - /// The container. - /// The access condition to use. - private async Task ContainerReadWriteExpectLeaseSuccessAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null); - await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null); - await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null); - await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null); - } - - [TestMethod] - /// [Description("Test reading the container lease status after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeaseStatusTestAsync() - { - string leaseId; - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Check uninitialized lease status - await SetUnleasedStateAsync(leasedContainer); - Assert.AreEqual(LeaseStatus.Unspecified, leasedContainer.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedContainer.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedContainer.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - await SetUnleasedStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - await SetRenewedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - await SetRenewedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await leasedContainer.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - await SetBreakingStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - await SetTimeBrokenStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - await SetTimeBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /*proposed lease ID */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - await SetInstantBrokenStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - await SetExpiredStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - await this.DeleteAllAsync(); - } - - /// - /// Checks the lease status of a container, both from its attributes and from a container listing. - /// - /// The container to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private async Task CheckLeaseStatusAsync( - CloudBlobContainer container, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - await container.FetchAttributesAsync(); - Assert.AreEqual(expectedStatus, container.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, container.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, container.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - ContainerResultSegment containers = await this.blobClient.ListContainersSegmentedAsync(container.Name, ContainerListingDetails.None, null, null, null, null); - BlobContainerProperties propertiesInListing = (from CloudBlobContainer c in containers.Results - where c.Name == container.Name - select c.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListContainers)"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MD5FlagsTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MD5FlagsTest.cs deleted file mode 100644 index 3a8c3403d983c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MD5FlagsTest.cs +++ /dev/null @@ -1,284 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class MD5FlagsTest : BlobTestBase - { - [TestMethod] - /// [Description("Test StoreBlobContentMD5 flag with UploadFromStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task StoreBlobContentMD5TestAsync() - { - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = false, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - ICloudBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithMD5, null); - } - await blob.FetchAttributesAsync(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob2"); - using (Stream stream = new NonSeekableMemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithNoMD5, null); - } - await blob.FetchAttributesAsync(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetBlockBlobReference("blob3"); - using (Stream stream = new NonSeekableMemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream()); - } - await blob.FetchAttributesAsync(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob4"); - using (Stream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithMD5, null); - } - await blob.FetchAttributesAsync(); - Assert.IsNotNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob5"); - using (Stream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithNoMD5, null); - } - await blob.FetchAttributesAsync(); - Assert.IsNull(blob.Properties.ContentMD5); - - blob = container.GetPageBlobReference("blob6"); - using (Stream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream.AsInputStream()); - } - await blob.FetchAttributesAsync(); - Assert.IsNull(blob.Properties.ContentMD5); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test DisableContentMD5Validation flag with DownloadToStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task DisableContentMD5ValidationTestAsync() - { - byte[] buffer = new byte[1024]; - Random random = new Random(); - random.NextBytes(buffer); - - BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - StoreBlobContentMD5 = true, - }; - BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() - { - DisableContentMD5Validation = false, - StoreBlobContentMD5 = true, - }; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream stream = new NonSeekableMemoryStream(buffer)) - { - await blockBlob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithMD5, null); - } - - using (Stream stream = new MemoryStream()) - { - await blockBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithMD5, null); - await blockBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithNoMD5, null); - - using (IRandomAccessStreamWithContentType blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - - using (IRandomAccessStreamWithContentType blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - - blockBlob.Properties.ContentMD5 = "MDAwMDAwMDA="; - await blockBlob.SetPropertiesAsync(); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blockBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithMD5, opContext), - opContext, - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - await blockBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithNoMD5, null); - - using (IRandomAccessStreamWithContentType blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - TestHelper.ExpectedException( - () => - { - int read; - do - { - read = blobStreamForRead.Read(buffer, 0, buffer.Length); - } - while (read > 0); - }, - "Downloading a blob with invalid MD5 should fail"); - } - - using (IRandomAccessStreamWithContentType blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - } - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - using (Stream stream = new MemoryStream(buffer)) - { - await pageBlob.UploadFromStreamAsync(stream.AsInputStream(), null, optionsWithMD5, null); - } - - using (Stream stream = new MemoryStream()) - { - await pageBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithMD5, null); - await pageBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithNoMD5, null); - - using (IRandomAccessStreamWithContentType blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - - using (IRandomAccessStreamWithContentType blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - - pageBlob.Properties.ContentMD5 = "MDAwMDAwMDA="; - await pageBlob.SetPropertiesAsync(); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await pageBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithMD5, opContext), - opContext, - "Downloading a blob with invalid MD5 should fail", - HttpStatusCode.OK); - await pageBlob.DownloadToStreamAsync(stream.AsOutputStream(), null, optionsWithNoMD5, null); - - using (IRandomAccessStreamWithContentType blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - TestHelper.ExpectedException( - () => - { - int read; - do - { - read = blobStreamForRead.Read(buffer, 0, buffer.Length); - } - while (read > 0); - }, - "Downloading a blob with invalid MD5 should fail"); - } - - using (IRandomAccessStreamWithContentType blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, null)) - { - Stream blobStreamForRead = blobStream.AsStreamForRead(); - int read; - do - { - read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); - } - while (read > 0); - } - } - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MemoryOutputStream.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MemoryOutputStream.cs deleted file mode 100644 index 13eaf20761b94..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/MemoryOutputStream.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System.IO; -using Windows.Foundation; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - internal sealed class MemoryOutputStream : IOutputStream - { - private IOutputStream outputStream; - - public MemoryStream UnderlyingStream { get; private set; } - - public MemoryOutputStream() - { - this.UnderlyingStream = new MemoryStream(); - this.outputStream = this.UnderlyingStream.AsOutputStream(); - } - - public IAsyncOperation FlushAsync() - { - return this.outputStream.FlushAsync(); - } - - public IAsyncOperationWithProgress WriteAsync(IBuffer buffer) - { - return this.outputStream.WriteAsync(buffer); - } - - public void Dispose() - { - if (this.outputStream != null) - { - this.outputStream.Dispose(); - this.outputStream = null; - } - - if (this.UnderlyingStream != null) - { - this.UnderlyingStream.Dispose(); - this.UnderlyingStream = null; - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/SASTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/SASTests.cs deleted file mode 100644 index f6234ee465614..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Blob/SASTests.cs +++ /dev/null @@ -1,296 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class SASTests : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - this.testContainer.CreateAsync().AsTask().Wait(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.DeleteAsync().AsTask().Wait(); - this.testContainer = null; - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - private static async Task TestAccessAsync(string sasToken, SharedAccessBlobPermissions permissions, CloudBlobContainer container, ICloudBlob blob) - { - OperationContext operationContext = new OperationContext(); - StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ? - new StorageCredentials() : - new StorageCredentials(sasToken); - - if (container != null) - { - container = new CloudBlobContainer(container.Uri, credentials); - if (blob.BlobType == BlobType.BlockBlob) - { - blob = container.GetBlockBlobReference(blob.Name); - } - else - { - blob = container.GetPageBlobReference(blob.Name); - } - } - else - { - if (blob.BlobType == BlobType.BlockBlob) - { - blob = new CloudBlockBlob(blob.Uri, credentials); - } - else - { - blob = new CloudPageBlob(blob.Uri, credentials); - } - } - - if (container != null) - { - if ((permissions & SharedAccessBlobPermissions.List) == SharedAccessBlobPermissions.List) - { - await container.ListBlobsSegmentedAsync(null); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, null, null, null, operationContext), - operationContext, - "List blobs while SAS does not allow for listing", - HttpStatusCode.NotFound); - } - } - - if ((permissions & SharedAccessBlobPermissions.Read) == SharedAccessBlobPermissions.Read) - { - await blob.FetchAttributesAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.FetchAttributesAsync(null, null, operationContext), - operationContext, - "Fetch blob attributes while SAS does not allow for reading", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Write) == SharedAccessBlobPermissions.Write) - { - await blob.SetMetadataAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(null, null, operationContext), - operationContext, - "Set blob metadata while SAS does not allow for writing", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Delete) == SharedAccessBlobPermissions.Delete) - { - await blob.DeleteAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DeleteAsync(DeleteSnapshotsOption.None, null, null, operationContext), - operationContext, - "Delete blob while SAS does not allow for deleting", - HttpStatusCode.NotFound); - } - } - - private static async Task TestBlobSASAsync(ICloudBlob testBlob, SharedAccessBlobPermissions permissions) - { - await UploadTextAsync(testBlob, "blob", Encoding.UTF8); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - - string sasToken = testBlob.GetSharedAccessSignature(policy); - await SASTests.TestAccessAsync(sasToken, permissions, null, testBlob); - } - - [TestMethod] - // [Description("Test updateSASToken")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerUpdateSASTokenAsync() - { - // Create a policy with read/write acces and get SAS. - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - await TestAccessAsync(sasToken, SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, this.testContainer, testBlockBlob); - - StorageCredentials creds = new StorageCredentials(sasToken); - - // Change the policy to only read and update SAS. - SharedAccessBlobPolicy policy2 = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read - }; - string sasToken2 = this.testContainer.GetSharedAccessSignature(policy2); - creds.UpdateSASToken(sasToken2); - - // Extra check to make sure that we have actually uopdated the SAS token. - CloudBlobContainer container = new CloudBlobContainer(this.testContainer.Uri, creds); - CloudBlockBlob blob = container.GetBlockBlobReference("blockblob2"); - OperationContext operationContext = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await UploadTextAsync(blob, "blob", Encoding.UTF8, null, null, operationContext), - operationContext, - "Writing to a blob while SAS does not allow for writing", - HttpStatusCode.NotFound); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - await testPageBlob.CreateAsync(0); - await TestAccessAsync(sasToken2, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - - } - - [TestMethod] - /// [Description("Test all combinations of blob permissions against a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSASCombinationsAsync() - { - for (int i = 1; i < 16; i++) - { - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob" + i); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - await SASTests.TestAccessAsync(sasToken, permissions, this.testContainer, testBlockBlob); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob" + i); - await UploadTextAsync(testPageBlob, "blob", Encoding.UTF8); - await SASTests.TestAccessAsync(sasToken, permissions, this.testContainer, testPageBlob); - } - } - - [TestMethod] - /// [Description("Test access on a public container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerPublicAccessAsync() - { - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - await UploadTextAsync(testPageBlob, "blob", Encoding.UTF8); - - BlobContainerPermissions permissions = new BlobContainerPermissions(); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - await this.testContainer.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - - permissions.PublicAccess = BlobContainerPublicAccessType.Blob; - await this.testContainer.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - } - - [TestMethod] - /// [Description("Test all combinations of blob permissions against a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSASCombinationsAsync() - { - for (int i = 1; i < 8; i++) - { - CloudBlockBlob testBlob = this.testContainer.GetBlockBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - await SASTests.TestBlobSASAsync(testBlob, permissions); - } - } - - [TestMethod] - /// [Description("Test all combinations of blob permissions against a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSASCombinationsAsync() - { - for (int i = 1; i < 8; i++) - { - CloudPageBlob testBlob = this.testContainer.GetPageBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - await SASTests.TestBlobSASAsync(testBlob, permissions); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/LoggingTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/LoggingTests.cs deleted file mode 100644 index 040aeef5c3386..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/LoggingTests.cs +++ /dev/null @@ -1,92 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Diagnostics; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Blob; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - [TestClass] - public class LoggingTests : TestBase - { - private TestLogListener traceListener; - - [TestInitialize] - public void TestInitialize() - { - this.traceListener = new TestLogListener(); - TestLogListener.Start(); - } - - [TestCleanup] - public void TestCleanup() - { - TestLogListener.Stop(); - } - - [TestMethod] - /// [Description("Do a set of operations and verify if everything is logged correctly")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task LoggingTestAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("logging" + Guid.NewGuid().ToString("N")); - try - { - OperationContext operationContext = new OperationContext(); - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - await TestHelper.ExpectedExceptionAsync( - async () => await container.FetchAttributesAsync(null, null, operationContext), - operationContext, - "Fetching a non-existent container's attributes should fail", - HttpStatusCode.NotFound); - Assert.AreEqual(1, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(1, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - await container.CreateIfNotExistsAsync(null, operationContext); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(1, TestLogListener.WarningCount); - Assert.AreEqual(operationContext.ClientRequestID, TestLogListener.LastRequestID); - - string lastLoggedRequestID = TestLogListener.LastRequestID; - operationContext.ClientRequestID = Guid.NewGuid().ToString(); - operationContext.LogLevel = LogLevel.Off; - await container.DeleteIfExistsAsync(null, null, operationContext); - Assert.AreEqual(2, TestLogListener.RequestCount); - Assert.AreEqual(1, TestLogListener.ErrorCount); - Assert.AreEqual(1, TestLogListener.WarningCount); - Assert.AreEqual(lastLoggedRequestID, TestLogListener.LastRequestID); - } - finally - { - container.DeleteIfExistsAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/MultiBufferMemoryStreamTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/MultiBufferMemoryStreamTests.cs deleted file mode 100644 index 939b60ce6f504..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/MultiBufferMemoryStreamTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Core.Executor; -using Microsoft.WindowsAzure.Storage.Core.Util; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - [TestClass] - public class MultiBufferMemoryStreamTests : TestBase - { - [TestMethod] - /// [Description("Copy between a MemoryStream and a MultiBufferMemoryStream")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task WriteToMultiBufferMemoryStreamTestAsync() - { - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - - MultiBufferMemoryStream stream2 = new MultiBufferMemoryStream(null /* bufferManager */); - await stream1.WriteToAsync(stream2, null, null, false, tempExecutionState, null, CancellationToken.None); - stream1.Seek(0, SeekOrigin.Begin); - stream2.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - MultiBufferMemoryStream stream3 = new MultiBufferMemoryStream(null /* bufferManager */); - await TestHelper.ExpectedExceptionAsync( - () => stream2.FastCopyToAsync(stream3, DateTime.Now.AddMinutes(-1)), - "Past expiration time should immediately fail"); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - await stream2.FastCopyToAsync(stream3, DateTime.Now.AddHours(1)); - stream2.Seek(0, SeekOrigin.Begin); - stream3.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream2, stream3); - - MultiBufferMemoryStream stream4 = new MultiBufferMemoryStream(null /* bufferManager */, 12345); - await stream3.FastCopyToAsync(stream4, null); - stream3.Seek(0, SeekOrigin.Begin); - stream4.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream3, stream4); - - MemoryStream stream5 = new MemoryStream(); - await stream4.WriteToAsync(stream5, null, null, false, tempExecutionState, null, CancellationToken.None); - stream4.Seek(0, SeekOrigin.Begin); - stream5.Seek(0, SeekOrigin.Begin); - TestHelper.AssertStreamsAreEqual(stream4, stream5); - - TestHelper.AssertStreamsAreEqual(stream1, stream5); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/OperationContextUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/OperationContextUnitTests.cs deleted file mode 100644 index 2ecaf2156b6a7..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/OperationContextUnitTests.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage.Blob; - using System; - using System.Threading.Tasks; - - [TestClass] - public class OperationContextUnitTests : TestBase - { - [TestMethod] - /// [Description("Test start / end time on OperationContext")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task OpContextTestStartEndTimeAsync() - { - CloudBlobClient blobClient = TestBase.GenerateCloudBlobClient(); - - DateTime start = DateTime.Now; - OperationContext ctx = new OperationContext(); - - await blobClient.GetContainerReference("test").CreateIfNotExistsAsync(null, ctx); - Assert.IsNotNull(ctx.StartTime, "StartTime not set"); - Assert.IsTrue(ctx.StartTime >= start, "StartTime not set correctly"); - Assert.IsNotNull(ctx.EndTime, "EndTime not set"); - Assert.IsTrue(ctx.EndTime <= DateTime.Now, "EndTime not set correctly"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/RetryPoliciesTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/RetryPoliciesTests.cs deleted file mode 100644 index 847ef3152bf14..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/RetryPoliciesTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage.Blob; - using System; - using System.Diagnostics; - using System.Threading; - using System.Threading.Tasks; - - [TestClass] - public class RetryPoliciesTests : TestBase - { - [TestMethod] - /// [Description("Test to ensure that the time when we wait for a retry is cancellable")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task RetryDelayShouldBeCancellableAsync() - { - TaskCompletionSource responseTask = new TaskCompletionSource(); - BlobRequestOptions options = new BlobRequestOptions(); - options.RetryPolicy = new AlwaysRetry(TimeSpan.FromMinutes(1), 1); - OperationContext context = new OperationContext(); - context.ResponseReceived += (sender, e) => responseTask.SetResult(true); - - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("test" + DateTime.UtcNow.Ticks.ToString()); - CancellationTokenSource token = new CancellationTokenSource(); - Task task = container.FetchAttributesAsync(null, options, context).AsTask(token.Token); - - await responseTask.Task; - await Task.Delay(10 * 1000); - - Stopwatch stopwatch = Stopwatch.StartNew(); - - try - { - token.Cancel(); - await task; - } - catch (Exception) - { - // This is expected, because we went for an invalid domain name. - } - - stopwatch.Stop(); - - Assert.IsTrue(stopwatch.Elapsed < TimeSpan.FromSeconds(10), stopwatch.Elapsed.ToString()); - Assert.AreEqual(1, context.RequestResults.Count); - } - - [TestMethod] - /// [Description("Setting retry policy to null should not throw an exception")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task NullRetryPolicyTestAsync() - { - CloudBlobClient blobClient = TestBase.GenerateCloudBlobClient(); - blobClient.RetryPolicy = null; - - CloudBlobContainer container = blobClient.GetContainerReference("test"); - await container.ExistsAsync(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/TestLogListener.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/TestLogListener.cs deleted file mode 100644 index 59db95b3a436d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/TestLogListener.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Diagnostics; -using System.Diagnostics.Tracing; - -namespace Microsoft.WindowsAzure.Storage.Core -{ - public partial class TestLogListener : EventListener - { - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - Debug.WriteLine(eventData.Payload[0]); - TestLogListener.ProcessMessage(TestLogListener.MapLogLevel(eventData.Level), eventData.Payload[0].ToString()); - } - - protected override void OnEventSourceCreated(EventSource eventSource) - { - base.OnEventSourceCreated(eventSource); - - if (eventSource.Name.Equals(Constants.LogSourceName)) - { - this.EnableEvents(eventSource, EventLevel.Verbose); - } - } - - private static LogLevel MapLogLevel(EventLevel level) - { - switch (level) - { - case EventLevel.Error: - return LogLevel.Error; - - case EventLevel.Warning: - return LogLevel.Warning; - - case EventLevel.Informational: - return LogLevel.Informational; - - case EventLevel.Verbose: - return LogLevel.Verbose; - - default: - throw new InvalidOperationException(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/WriteToAsyncTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/WriteToAsyncTests.cs deleted file mode 100644 index 3ac4e0dbfdb8d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Core/WriteToAsyncTests.cs +++ /dev/null @@ -1,155 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Core -{ - using System; - using System.IO; - using System.Threading; - using System.Threading.Tasks; - - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage.Core.Executor; - using Microsoft.WindowsAzure.Storage.Core.Util; - - [TestClass] - public class WriteToAsyncTests : TestBase - { - [TestMethod] - /// [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task StreamWriteAsyncTest() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test basic write - await stream1.WriteToAsync(stream2, null, null, false, tempExecutionState, null, CancellationToken.None); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - stream2.Dispose(); - stream2 = new MemoryStream(); - - await TestHelper.ExpectedExceptionAsync( - async () => await stream1.WriteToAsync(stream2, 1024, 1024, false, tempExecutionState, null, CancellationToken.None), - "Parameters copyLength and maxLength cannot be passed simultaneously."); - - stream1.Dispose(); - stream2.Dispose(); - } - - [TestMethod] - /// [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task StreamWriteAsyncTestCopyLengthBoundary() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test write with exact number of bytes - await stream1.WriteToAsync(stream2, stream1.Length, null, false, tempExecutionState, null, CancellationToken.None); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - stream2.Dispose(); - stream2 = new MemoryStream(); - - // Test write with one less byte - await stream1.WriteToAsync(stream2, stream1.Length - 1, null, false, tempExecutionState, null, CancellationToken.None); - stream1.Position = 0; - - Assert.AreEqual(stream1.Length - 1, stream2.Length); - TestHelper.AssertStreamsAreEqualAtIndex(stream1, stream2, 0, 0, (int)stream1.Length - 1); - - stream2.Dispose(); - stream2 = new MemoryStream(); - - // Test with copyLength greater than length - await TestHelper.ExpectedExceptionAsync( - async () => await stream1.WriteToAsync(stream2, stream1.Length + 1, null, false, tempExecutionState, null, CancellationToken.None), - "The given stream does not contain the requested number of bytes from its given position."); - stream1.Position = 0; - - stream1.Dispose(); - stream2.Dispose(); - } - - [TestMethod] - /// [Description("Copy between a MemoryStream using WriteToSync at different lengths.")] - [TestCategory(ComponentCategory.Core)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task StreamWriteAsyncTestMaxLengthBoundary() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - MemoryStream stream1 = new MemoryStream(buffer); - MemoryStream stream2 = new MemoryStream(); - - OperationContext tempOperationContext = new OperationContext(); - RESTCommand cmd = new RESTCommand(TestBase.StorageCredentials, null); - ExecutionState tempExecutionState = new ExecutionState(cmd, null, tempOperationContext); - - // Test write with exact number of bytes - await stream1.WriteToAsync(stream2, null, stream1.Length, false, tempExecutionState, null, CancellationToken.None); - stream1.Position = 0; - - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - stream2.Dispose(); - stream2 = new MemoryStream(); - - // Test write with one less byte - await TestHelper.ExpectedExceptionAsync( - async () => await stream1.WriteToAsync(stream2, null, stream1.Length - 1, false, tempExecutionState, null, CancellationToken.None), - "Stream is longer than the allowed length."); - stream1.Position = 0; - - stream2.Dispose(); - stream2 = new MemoryStream(); - - // Test with count greater than length - await stream1.WriteToAsync(stream2, null, stream1.Length + 1, false, tempExecutionState, null, CancellationToken.None); - stream1.Position = 0; - - // Entire stream should have been copied - TestHelper.AssertStreamsAreEqual(stream1, stream2); - - stream1.Dispose(); - stream2.Dispose(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestLogo.png b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestLogo.png deleted file mode 100644 index ebd735aa9352c..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestLogo.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSmallLogo.png b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSmallLogo.png deleted file mode 100644 index 92dd1058fbfb7..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSmallLogo.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSplashScreen.png b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSplashScreen.png deleted file mode 100644 index 193187f108f50..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestSplashScreen.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestStoreLogo.png b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestStoreLogo.png deleted file mode 100644 index 3765186d055fb..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Images/UnitTestStoreLogo.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/MSSharedLibKey.snk b/microsoft-azure-api/Services/Storage/Test/Unit/RT/MSSharedLibKey.snk deleted file mode 100644 index 695f1b38774e8..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/MSSharedLibKey.snk and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Package.appxmanifest b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Package.appxmanifest deleted file mode 100644 index 64458bde143fe..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Package.appxmanifest +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Microsoft.WindowsAzure.Storage.Test - WindowsAzure - Images\UnitTestStoreLogo.png - Microsoft.WindowsAzure.Storage.Test - - - 6.2 - 6.2 - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Properties/AssemblyInfo.cs deleted file mode 100644 index fecf24f30bc45..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Reflection; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.StorageRT.Test.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueClientTest.cs deleted file mode 100644 index fb53ecca079a0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueClientTest.cs +++ /dev/null @@ -1,187 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueClientTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - //[Description("A test checks basic function of CloudQueueClient.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint); - CloudQueueClient queueClient = new CloudQueueClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(queueClient.BaseUri.ToString().StartsWith(TestBase.TargetTenantConfig.QueueServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, queueClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, queueClient.AuthenticationScheme); - } - - [TestMethod] - // [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientListQueuesBasicAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = GenerateNewQueueName(); - List queueNames = new List(); - int count = 30; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueResultSegment emptyResults = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.All, null, null, null, null); - Assert.AreEqual(0, emptyResults.Results.Count()); - - foreach (string name in queueNames) - { - await client.GetQueueReference(name).CreateAsync(); - } - - QueueResultSegment results = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.All, null, null, null, null); - - foreach (CloudQueue queue in results.Results) - { - if (queueNames.Remove(queue.Name)) - { - await queue.DeleteAsync(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(count, results.Results.Count()); - } - - [TestMethod] - // [Description("Test Create Queue with Shared Key Lite")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientCreateQueueSharedKeyLiteAsync() - { - CloudQueueClient queueClient = GenerateCloudQueueClient(); - queueClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string queueName = GenerateNewQueueName(); - CloudQueue queue = queueClient.GetQueueReference(queueName); - await queue.CreateAsync(); - - bool exists = await queue.ExistsAsync(); - Assert.IsTrue(exists); - } - - [TestMethod] - // [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientListQueuesSegmentedAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "rtqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, null, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - await client.GetQueueReference(name).CreateAsync(); - } - - do - { - QueueResultSegment segment = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, 10, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - await queue.DeleteAsync(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueMessageTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueMessageTest.cs deleted file mode 100644 index 155b47178e019..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueMessageTest.cs +++ /dev/null @@ -1,261 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueMessageTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - // [Description("Test CloudQueueMessage constructor.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateIfNotExistsAsync(); - - CloudQueueMessage message = new CloudQueueMessage(Guid.NewGuid().ToString()); - await queue.AddMessageAsync(message); - - CloudQueueMessage retrMessage = await queue.GetMessageAsync(); - string messageId = retrMessage.Id; - string popReceipt = retrMessage.PopReceipt; - - // Recreate the message using the messageId and popReceipt. - CloudQueueMessage newMessage = new CloudQueueMessage(messageId, popReceipt); - Assert.AreEqual(messageId, newMessage.Id); - Assert.AreEqual(popReceipt, newMessage.PopReceipt); - - await queue.UpdateMessageAsync(newMessage, TimeSpan.FromSeconds(30), MessageUpdateFields.Visibility); - CloudQueueMessage retrMessage2 = await queue.GetMessageAsync(); - Assert.AreEqual(null, retrMessage2); - } - finally - { - queue.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Test add/delete message")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueMessageAddDelete() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - - await queue.AddMessageAsync(new CloudQueueMessage("abcde")); - - CloudQueueMessage receivedMessage1 = await queue.GetMessageAsync(); - - await queue.DeleteMessageAsync(receivedMessage1.Id, receivedMessage1.PopReceipt); - - CloudQueueMessage receivedMessage2 = await queue.GetMessageAsync(); - Assert.IsNull(receivedMessage2); - } - - [TestMethod] - //[Description("Test whether get message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - CloudQueueMessage emptyMessage = await queue.GetMessageAsync(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.GetMessageAsync(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Test whether get messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetMessagesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - int messageCount = 30; - - List emptyMessages = (await queue.GetMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = (await queue.GetMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Test whether peek message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueuePeekMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - CloudQueueMessage emptyMessage = await queue.PeekMessageAsync(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.PeekMessageAsync(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Test whether peek messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueuePeekMessagesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - int messageCount = 30; - - List emptyMessages = (await queue.PeekMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = (await queue.PeekMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Test whether clear message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClearMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.PeekMessageAsync(); - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - await queue.ClearAsync(); - Assert.IsNull(await queue.PeekMessageAsync()); - await queue.DeleteAsync(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueTest.cs deleted file mode 100644 index 8befb8996a785..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/CloudQueueTest.cs +++ /dev/null @@ -1,354 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using System; -using System.Net; -using System.Threading.Tasks; -using Windows.Globalization; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - /// [Description("Create and delete a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateAndDeleteAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - await queue.CreateAsync(); - await queue.DeleteAsync(); - } - - [TestMethod] - /// [Description("Try to create a queue after it is created")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateIfNotExistsAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - Assert.IsTrue(await queue.CreateIfNotExistsAsync()); - Assert.IsFalse(await queue.CreateIfNotExistsAsync()); - } - finally - { - queue.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - /// [Description("Try to delete a non-existing queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueDeleteIfExistsAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - Assert.IsFalse(await queue.DeleteIfExistsAsync()); - await queue.CreateAsync(); - Assert.IsTrue(await queue.DeleteIfExistsAsync()); - Assert.IsFalse(await queue.DeleteIfExistsAsync()); - } - - [TestMethod] - //[Description("Set/get queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetSetPermissionsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - QueuePermissions emptyPermission = await queue.GetPermissionsAsync(); - Assert.AreEqual(emptyPermission.SharedAccessPolicies.Count, 0); - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - await queue.FetchAttributesAsync(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - QueuePermissions permissionsToRetrieve = await queueToRetrieve.GetPermissionsAsync(); - - Assert.AreEqual(permissions.SharedAccessPolicies.Count, permissionsToRetrieve.SharedAccessPolicies.Count); - //Assert.AreEqual(start, permissionsToRetrieve.SharedAccessPolicies[id].SharedAccessStartTime.Value.UtcDateTime); - //Assert.AreEqual(expiry, permissionsToRetrieve.SharedAccessPolicies[id].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(permissions.SharedAccessPolicies[id].Permissions, permissionsToRetrieve.SharedAccessPolicies[id].Permissions); - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Set/get a queue with metadata")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueSetGetMetadataAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - queue.Metadata.Add("key1", "value1"); - await queue.SetMetadataAsync(); - - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(1, queueToRetrieve.Metadata.Count); - Assert.AreEqual("value1", queueToRetrieve.Metadata["key1"]); - - queue.Metadata.Clear(); - await queue.SetMetadataAsync(); - - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - await queue.DeleteAsync(); - } - - [TestMethod] - //[Description("Test queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task QueueSASTestAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - - CloudStorageAccount sasAcc = new CloudStorageAccount(sasCredsFromId, new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint), new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint), new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint)); - CloudQueueClient sasClient = sasAcc.CreateCloudQueueClient(); - - CloudQueue sasQueueFromSasUri = new CloudQueue(sasClient.Credentials.TransformUri(queue.Uri)); - CloudQueueMessage receivedMessage = await sasQueueFromSasUri.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage.AsString); - - CloudQueue sasQueueFromSasUri1 = new CloudQueue(new Uri(queue.Uri.ToString() + sasTokenFromId)); - CloudQueueMessage receivedMessage1 = await sasQueueFromSasUri1.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage2 = await sasQueueFromId.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage3 = await sasQueueFromPolicy.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage3.AsString); - await queue.DeleteAsync(); - } - - [TestMethod] - // [Description("Update queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task UpdateQueueSASTestAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - SharedAccessQueuePolicy policy = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages, - }; - string id = Guid.NewGuid().ToString(); - string sasToken = queue.GetSharedAccessSignature(policy, null); - - StorageCredentials sasCreds = new StorageCredentials(sasToken); - CloudQueue sasQueue = new CloudQueue(queue.Uri, sasCreds); - OperationContext context = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await sasQueue.PeekMessageAsync(null, context), - context, - "Peek when Sas does not allow Read access on the queue", - HttpStatusCode.NotFound); - - await sasQueue.AddMessageAsync(message); - - SharedAccessQueuePolicy policy2 = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read, - }; - - string sasToken2 = queue.GetSharedAccessSignature(policy2, null); - sasCreds.UpdateSASToken(sasToken2); - sasQueue = new CloudQueue(queue.Uri, sasCreds); - - await sasQueue.PeekMessageAsync(); - } - finally - { - queue.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("Test queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task QueueRegionalSASTestAsync() - { - string currentPrimaryLanguage = ApplicationLanguages.PrimaryLanguageOverride; - ApplicationLanguages.PrimaryLanguageOverride = "it"; - - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage1 = await sasQueueFromId.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage2 = await sasQueueFromPolicy.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - } - finally - { - ApplicationLanguages.PrimaryLanguageOverride = currentPrimaryLanguage; - queue.DeleteAsync().AsTask().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/ExceptionHResultTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/ExceptionHResultTest.cs deleted file mode 100644 index 9acd524c27cb4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/ExceptionHResultTest.cs +++ /dev/null @@ -1,70 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Core.Util; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class ExceptionHResultTest : TestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateNegativeBadRequestAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - try - { - string name = Guid.NewGuid().ToString("N"); - CloudQueue queue = client.GetQueueReference(name); - await queue.FetchAttributesAsync(); - Assert.Fail(); - } - catch (Exception e) - { - Assert.AreEqual(WindowsAzureErrorCode.HttpNotFound, e.HResult); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/QueueAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/QueueAnalyticsUnitTests.cs deleted file mode 100644 index 48b8927aa60c1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Queue/QueueAnalyticsUnitTests.cs +++ /dev/null @@ -1,359 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class QueueAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public QueueAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudQueueClient client = GenerateCloudQueueClient(); - startProperties = client.GetServicePropertiesAsync().AsTask().Result; - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudQueueClient client = GenerateCloudQueueClient(); - client.SetServicePropertiesAsync(startProperties).AsTask().Wait(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - [TestMethod] - /// [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsRoundTripAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - /// [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsDisableAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsDefaultServiceVersionThrowsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - await client.SetServicePropertiesAsync(props, null, ctx); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.Exception.Message, "XML specified is not syntactically valid."); - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - return; - } - - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - - [TestMethod] - /// [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsLoggingOperationsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsMetricsLevelAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsRetentionPoliciesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT.csproj b/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT.csproj deleted file mode 100644 index 4b02716541f69..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT.csproj +++ /dev/null @@ -1,161 +0,0 @@ - - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {B0A800BB-D01B-42C0-8FBC-FA868C29C8B7} - Library - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.StorageRT.Test - en-US - 512 - {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - RT_Test_TemporaryKey.pfx - 5E96456B12159A670EAF6D01EC0DEA1921A4BB57 - True - - - true - full - false - bin\Debug\ - TRACE;DEBUG;NETFX_CORE;WINDOWS_RT - prompt - 4 - - - true - MSSharedLibKey.snk - true - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE;WINDOWS_RT - prompt - 4 - - - True - true - - - - - - - - - - - Blob\Blob - - - Core\Core - - - Queue\Queue - - - Table\Entities\Table - - - TestConfigProcess\TestConfigProcess - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - - - Readme.txt - - - TestConfigurations.xml - Always - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - - - - {42cb7861-70bb-4f34-a815-4355e6ea2589} - RT %28Lib\RT%29 - - - {91930f51-683b-4933-a452-7d8ddfdbb1ac} - RTTable - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT_Test_TemporaryKey.pfx b/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT_Test_TemporaryKey.pfx deleted file mode 100644 index cca11db69e24e..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/RT/RT_Test_TemporaryKey.pfx and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableCRUDUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableCRUDUnitTests.cs deleted file mode 100644 index 4e2c323ac2201..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableCRUDUnitTests.cs +++ /dev/null @@ -1,308 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Summary description for CloudTableCRUDUnitTests - /// - [TestClass] - public class CloudTableCRUDUnitTests : TableTestBase - { - #region Locals + Ctors - public CloudTableCRUDUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Table Create - - [TestMethod] - // [Description("Test Table Create - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("Test Table Create When Table Already Exists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateAlreadyExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - - // This should throw with no retries - await tableRef.CreateAsync(null, ctx); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.ExtendedErrorInformation.ErrorCode, "TableAlreadyExists"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Table CreateIfNotExists - - [TestMethod] - // [Description("Test Table CreateIfNotExists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateIfNotExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - Assert.IsTrue(await tableRef.CreateIfNotExistsAsync()); - Assert.IsTrue(await tableRef.ExistsAsync()); - Assert.IsFalse(await tableRef.CreateIfNotExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Table Delete - - [TestMethod] - // [Description("Test Table Delete - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - await tableRef.DeleteAsync(); - Assert.IsFalse(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("Test Table Delete When Table Does Not Exist - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteWhenNotExistAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - - // This should throw with no retries - await tableRef.DeleteAsync(null, ctx); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.HttpStatusCode, 404); - Assert.AreEqual(ctx.LastResult.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Table DeleteIfExists - - [TestMethod] - // [Description("Test Table DeleteIfExists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteIfExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - Assert.IsFalse(await tableRef.DeleteIfExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - Assert.IsTrue(await tableRef.DeleteIfExistsAsync()); - Assert.IsFalse(await tableRef.DeleteIfExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Table Exists - - [TestMethod] - // [Description("Test Table Exists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - await tableRef.DeleteAsync(); - Assert.IsFalse(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableClientTest.cs deleted file mode 100644 index 22c6c894a5e53..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/CloudTableClientTest.cs +++ /dev/null @@ -1,247 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class CloudTableClientTest : TableTestBase - { - #region Locals + Ctors - public CloudTableClientTest() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // 20 random tables - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(GenerateRandomTableName()); - tableRef.CreateIfNotExistsAsync().AsTask().Wait(); - createdTables.Add(tableRef); - } - - prefixTablesPrefix = "prefixtable" + GenerateRandomTableName(); - // 20 tables with known prefix - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(prefixTablesPrefix + m.ToString()); - tableRef.CreateIfNotExistsAsync().AsTask().Wait(); - createdTables.Add(tableRef); - } - } - - private static string prefixTablesPrefix = null; - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - foreach (CloudTable t in createdTables) - { - try - { - t.DeleteIfExistsAsync().AsTask().Wait(); - } - catch (Exception) - { - } - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Ctor Tests - [TestMethod] - //// [Description("A test checks constructor of CloudTableClient.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - CloudTableClient tableClient = new CloudTableClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(tableClient.BaseUri.ToString().StartsWith(TestBase.TargetTenantConfig.TableServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, tableClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, tableClient.AuthenticationScheme); - } - #endregion - - #region List Tables Segmented - - [TestMethod] - // [Description("Test List Tables Segmented Basic Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedBasicAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - do - { - segment = await tableClient.ListTablesSegmentedAsync(segment != null ? segment.ContinuationToken : null); - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - } - - [TestMethod] - // [Description("Test List Tables Segmented MaxResults Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedMaxResultsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = await tableClient.ListTablesSegmentedAsync(string.Empty, 10, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - Assert.IsTrue(segCount >= totalResults.Count / 10); - } - - [TestMethod] - // [Description("Test List Tables Segmented With Prefix Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedWithPrefixAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = await tableClient.ListTablesSegmentedAsync(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, 20); - foreach (CloudTable tbl in totalResults) - { - Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); - } - } - - [TestMethod] - // [Description("Test List Tables Segmented with Shared Key Lite")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableClientListTablesSegmentedSharedKeyLite() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - TableResultSegment segment = null; - List totalResults = new List(); - - do - { - segment = await tableClient.ListTablesSegmentedAsync(segment != null ? segment.ContinuationToken : null); - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - Assert.IsTrue(totalResults.Count > 0); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasFunctionalTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasFunctionalTests.cs deleted file mode 100644 index f91f9bc9fb051..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasFunctionalTests.cs +++ /dev/null @@ -1,219 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableSasFunctionalTests : TableTestBase - { - #region Locals + Ctors - public TableSasFunctionalTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Permissions - - [TestMethod] - // [Description("Tests setting and getting table permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGetSetPermissionTestAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - await table.CreateAsync(); - - await table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions; - TablePermissions testPermissions; - - // Test new table permissions. - expectedPermissions = new TablePermissions(); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Test setting empty permissions. - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a null policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.None, - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromDays(0.5), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Update, - SharedAccessStartTime = DateTimeOffset.Now + TimeSpan.FromHours(6), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(6.5) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasUnitTests.cs deleted file mode 100644 index 22d3159117afc..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/SAS/TableSasUnitTests.cs +++ /dev/null @@ -1,1141 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableSasUnitTests : TableTestBase - { - #region Locals + Ctors - public TableSasUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static void MyClassCleanup() { } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Constructor Tests - - [TestMethod] - // [Description("Test TableSas via various constructors Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSASConstructorsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - try - { - await table.CreateAsync(); - - await table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - // Prepare SAS authentication with full permissions - string sasToken = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null /* accessPolicyIdentifier */, - null /* startPk */, - null /* startRk */, - null /* endPk */, - null /* endRk */); - - CloudStorageAccount sasAccount; - StorageCredentials sasCreds; - CloudTableClient sasClient; - CloudTable sasTable; - Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - - // SAS via connection string parse - sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken)); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - - Assert.AreEqual(1, (await sasTable.ExecuteQuerySegmentedAsync(new TableQuery(), null)).Results.Count()); - - // SAS via account constructor - sasCreds = new StorageCredentials(sasToken); - sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri); - sasClient = sasAccount.CreateCloudTableClient(); - sasTable = sasClient.GetTableReference(table.Name); - Assert.AreEqual(1, (await sasTable.ExecuteQuerySegmentedAsync(new TableQuery(), null)).Results.Count()); - - // SAS via client constructor URI + Creds - sasCreds = new StorageCredentials(sasToken); - sasClient = new CloudTableClient(baseUri, sasCreds); - Assert.AreEqual(1, (await sasTable.ExecuteQuerySegmentedAsync(new TableQuery(), null)).Results.Count()); - - // SAS via CloudTable constructor Uri + Client - sasCreds = new StorageCredentials(sasToken); - sasTable = new CloudTable(table.Uri, tableClient.Credentials); - sasClient = sasTable.ServiceClient; - Assert.AreEqual(1, (await sasTable.ExecuteQuerySegmentedAsync(new TableQuery(), null)).Results.Count()); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Permissions - - [TestMethod] - // [Description("Tests setting and getting table permissions Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSetGetPermissionsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - - await table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions = new TablePermissions(); - TablePermissions testPermissions = await table.GetPermissionsAsync(); - - AssertPermissionsEqual(expectedPermissions, testPermissions); - - // Add a policy, check setting and getting. - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - testPermissions = await table.GetPermissionsAsync(); - AssertPermissionsEqual(expectedPermissions, testPermissions); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("Tests Null Access Policy")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSASNullAccessPolicyAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - - await table.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK"))); - - TablePermissions expectedPermissions = new TablePermissions(); - - // Add a policy - expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Add, - SharedAccessStartTime = DateTimeOffset.Now - TimeSpan.FromHours(1), - SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1) - }); - - await table.SetPermissionsAsync(expectedPermissions); - await Task.Delay(30 * 1000); - - // Generate the sasToken the user should use - string sasToken = table.GetSharedAccessSignature(null, expectedPermissions.SharedAccessPolicies.First().Key, "AAAA", null, "AAAA", null); - - CloudTable sasTable = new CloudTable(table.Uri, new StorageCredentials(sasToken)); - - await sasTable.ExecuteAsync(TableOperation.Insert(new DynamicTableEntity("AAAA", "foo"))); - - TableResult result = await sasTable.ExecuteAsync(TableOperation.Retrieve("AAAA", "foo")); - - Assert.IsNotNull(result.Result); - - // revoke table permissions - await table.SetPermissionsAsync(new TablePermissions()); - await Task.Delay(30 * 1000); - - OperationContext opContext = new OperationContext(); - try - { - await sasTable.ExecuteAsync(TableOperation.Insert(new DynamicTableEntity("AAAA", "foo2")), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(opContext.LastResult.HttpStatusCode, (int)HttpStatusCode.Forbidden); - } - - opContext = new OperationContext(); - try - { - result = await sasTable.ExecuteAsync(TableOperation.Retrieve("AAAA", "foo"), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(opContext.LastResult.HttpStatusCode, (int)HttpStatusCode.Forbidden); - } - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region SAS Operations - - [TestMethod] - // [Description("Tests table SAS with query permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasQueryTestAsync() - { - await TestTableSas(SharedAccessTablePermissions.Query); - } - - [TestMethod] - // [Description("Tests table SAS with delete permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasDeleteTestAsync() - { - await TestTableSas(SharedAccessTablePermissions.Delete); - } - - [TestMethod] - // [Description("Tests table SAS with process and update permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasUpdateTestAsync() - { - await TestTableSas(SharedAccessTablePermissions.Update); - } - - [TestMethod] - // [Description("Tests table SAS with add permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasAddTestAsync() - { - await TestTableSas(SharedAccessTablePermissions.Add); - } - - [TestMethod] - // [Description("Tests table SAS with full permissions.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasFullTestAsync() - { - await TestTableSas(SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// Various table range constraints are tested. - /// - /// The permissions to test. - internal async Task TestTableSas(SharedAccessTablePermissions accessPermissions) - { - string startPk = "M"; - string startRk = "F"; - string endPk = "S"; - string endRk = "T"; - - // No ranges specified - await TestTableSasWithRange(accessPermissions, null, null, null, null); - - // All ranges specified - await TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, endRk); - - // StartPk & StartRK specified - await TestTableSasWithRange(accessPermissions, startPk, startRk, null, null); - - // StartPk specified - await TestTableSasWithRange(accessPermissions, startPk, null, null, null); - - // EndPk & EndRK specified - await TestTableSasWithRange(accessPermissions, null, null, endPk, endRk); - - // EndPk specified - await TestTableSasWithRange(accessPermissions, null, null, endPk, null); - - // StartPk and EndPk specified - await TestTableSasWithRange(accessPermissions, startPk, null, endPk, null); - - // StartRk and StartRK and EndPk specified - await TestTableSasWithRange(accessPermissions, startPk, startRk, endPk, null); - - // StartRk and EndPK and EndPk specified - await TestTableSasWithRange(accessPermissions, startPk, null, endPk, endRk); - } - - /// - /// Tests table access permissions with SAS, using a stored policy and using permissions on the URI. - /// - /// The permissions to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - internal async Task TestTableSasWithRange( - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - - // Set up a policy - string identifier = Guid.NewGuid().ToString(); - TablePermissions permissions = new TablePermissions(); - permissions.SharedAccessPolicies.Add(identifier, new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddDays(1) - }); - - await table.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - // Prepare SAS authentication using access identifier - string sasString = table.GetSharedAccessSignature(new SharedAccessTablePolicy(), identifier, startPk, startRk, endPk, endRk); - CloudTableClient identifierSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Prepare SAS authentication using explicit policy - sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = accessPermissions, - SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30) - }, - null, - startPk, - startRk, - endPk, - endRk); - - CloudTableClient explicitSasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Point query - await TestPointQuery(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestPointQuery(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Add row - await TestAdd(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestAdd(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (merge) - await TestUpdateMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestUpdateMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Update row (replace) - await TestUpdateReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestUpdateReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Delete row - await TestDelete(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestDelete(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (merge) - await TestUpsertMerge(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestUpsertMerge(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - - // Upsert row (replace) - await TestUpsertReplace(identifierSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - await TestUpsertReplace(explicitSasClient, table.Name, accessPermissions, startPk, startRk, endPk, endRk); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - - /// - /// Test point queries entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestPointQuery( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Query) != 0; - - Action queryDelegate = (tableEntity, ctx) => - { - Task retrieveTask = testClient.GetTableReference(tableName).ExecuteAsync(TableOperationFactory.Retrieve(tableEntity.PartitionKey, tableEntity.RowKey), null, ctx).AsTask(); - - retrieveTask.Wait(); - - if (expectSuccess) - { - Assert.IsNotNull(retrieveTask.Result.Result); - } - else - { - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.OK); - } - }; - - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - queryDelegate, - "point query", - expectSuccess, - expectSuccess ? HttpStatusCode.OK : HttpStatusCode.NotFound); - } - - - /// - /// Test update (merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestUpdateMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity, ctx) => - { - // Merge entity - tableEntity.A = "10"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Merge(tableEntity), null, ctx).AsTask().Wait(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test update (replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestUpdateReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action updateDelegate = (tableEntity, ctx) => - { - // replace entity - tableEntity.A = "20"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Replace(tableEntity), null, ctx).AsTask().Wait(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Update) != 0; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - updateDelegate, - "update replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test adding entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestAdd( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action addDelegate = (tableEntity, ctx) => - { - // insert entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Insert(tableEntity), null, ctx).AsTask().Wait(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Add) != 0; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - addDelegate, - "add", - expectSuccess, - expectSuccess ? HttpStatusCode.Created : HttpStatusCode.NotFound); - } - - /// - /// Test deleting entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestDelete( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action deleteDelegate = (tableEntity, ctx) => - { - // delete entity - tableEntity.A = "10"; - tableEntity.ETag = "*"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Delete(tableEntity), null, ctx).AsTask().Wait(); - }; - - bool expectSuccess = (accessPermissions & SharedAccessTablePermissions.Delete) != 0; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - deleteDelegate, - "delete", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or merge) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestUpsertMerge( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity, ctx) => - { - // insert or merge entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.InsertOrMerge(tableEntity), null, ctx).AsTask().Wait(); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert merge", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test upsert (insert or replace) on entities inside and outside the given range. - /// - /// The table client to test. - /// The name of the table to test. - /// The access permissions of the table client. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - private async Task TestUpsertReplace( - CloudTableClient testClient, - string tableName, - SharedAccessTablePermissions accessPermissions, - string startPk, - string startRk, - string endPk, - string endRk) - { - Action upsertDelegate = (tableEntity, ctx) => - { - // insert or replace entity - tableEntity.A = "10"; - - testClient.GetTableReference(tableName).ExecuteAsync(TableOperation.InsertOrReplace(tableEntity), null, ctx).AsTask().Wait(); - }; - - SharedAccessTablePermissions upsertPermissions = (SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Add); - bool expectSuccess = (accessPermissions & upsertPermissions) == upsertPermissions; - - // Perform test - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - upsertDelegate, - "upsert replace", - expectSuccess, - expectSuccess ? HttpStatusCode.NoContent : HttpStatusCode.NotFound); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private async Task TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode) - { - await TestOperationWithRange( - tableName, - startPk, - startRk, - endPk, - endRk, - runOperationDelegate, - opName, - expectSuccess, - expectedStatusCode, - false /* isRangeQuery */); - } - - /// - /// Test a table operation on entities inside and outside the given range. - /// - /// The name of the table to test. - /// The start partition key range. - /// The start row key range. - /// The end partition key range. - /// The end row key range. - /// A delegate with the table operation to test. - /// The name of the operation being tested. - /// Whether the operation should succeed on entities within the range. - private async Task TestOperationWithRange( - string tableName, - string startPk, - string startRk, - string endPk, - string endRk, - Action runOperationDelegate, - string opName, - bool expectSuccess, - HttpStatusCode expectedStatusCode, - bool isRangeQuery) - { - CloudTableClient referenceClient = GenerateCloudTableClient(); - - string partitionKey = startPk ?? endPk ?? "M"; - string rowKey = startRk ?? endRk ?? "S"; - - // if we expect a success for creation - avoid inserting duplicate entities - BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey); - if (expectedStatusCode == HttpStatusCode.Created) - { - try - { - tableEntity.ETag = "*"; - await referenceClient.GetTableReference(tableName).ExecuteAsync(TableOperation.Delete(tableEntity)); - } - catch (Exception) - { - } - } - else - { - // only for add we should not be adding the entity - await referenceClient.GetTableReference(tableName).ExecuteAsync(TableOperation.InsertOrReplace(tableEntity)); - } - - if (expectSuccess) - { - runOperationDelegate(tableEntity, null); - } - else - { - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} without appropriate permission.", opName), - (int)HttpStatusCode.NotFound); - } - - if (startPk != null) - { - tableEntity.PartitionKey = "A"; - if (startPk.CompareTo(tableEntity.PartitionKey) <= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} before allowed partition key range", opName), - (int)HttpStatusCode.NotFound); - tableEntity.PartitionKey = partitionKey; - } - - if (endPk != null) - { - tableEntity.PartitionKey = "Z"; - if (endPk.CompareTo(tableEntity.PartitionKey) >= 0) - { - Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} after allowed partition key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.PartitionKey = partitionKey; - } - - if (startRk != null) - { - if (isRangeQuery || startPk != null) - { - tableEntity.PartitionKey = startPk; - tableEntity.RowKey = "A"; - if (startRk.CompareTo(tableEntity.RowKey) <= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} before allowed row key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - - if (endRk != null) - { - if (isRangeQuery || endPk != null) - { - tableEntity.PartitionKey = endPk; - tableEntity.RowKey = "Z"; - if (endRk.CompareTo(tableEntity.RowKey) >= 0) - { - Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\""); - } - - TestHelper.ExpectedException( - (ctx) => runOperationDelegate(tableEntity, ctx), - string.Format("{0} after allowed row key range", opName), - (int)HttpStatusCode.NotFound); - - tableEntity.RowKey = rowKey; - } - } - } - #endregion - - #region SAS Error Conditions - - //[TestMethod] // Disabled until service bug is fixed - // [Description("Attempt to use SAS to authenticate table operations that must not work with SAS.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasInvalidOperations() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - // Prepare SAS authentication with full permissions - string sasString = table.GetSharedAccessSignature( - new SharedAccessTablePolicy - { - Permissions = SharedAccessTablePermissions.Delete, - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30) - }, - null, - null, - null, - null, - null); - - CloudTableClient sasClient = new CloudTableClient(tableClient.BaseUri, new StorageCredentials(sasString)); - - // Construct a valid set of service properties to upload. - ServiceProperties properties = new ServiceProperties(); - properties.Logging.Version = "1.0"; - properties.Metrics.Version = "1.0"; - properties.Logging.RetentionDays = 9; - await sasClient.GetServicePropertiesAsync(); - await sasClient.SetServicePropertiesAsync(properties); - - // Test invalid client operations - // BUGBUG: ListTables hides the exception. We should fix this - // TestHelpers.ExpectedException(() => sasClient.ListTablesSegmented(), "List tables with SAS", HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasClient.GetServicePropertiesAsync().AsTask().Wait(), "Get service properties with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasClient.SetServicePropertiesAsync(properties).AsTask().Wait(), "Set service properties with SAS", (int)HttpStatusCode.NotFound); - - CloudTable sasTable = sasClient.GetTableReference(table.Name); - - // Verify that creation fails with SAS - TestHelper.ExpectedException((ctx) => sasTable.CreateAsync(null, ctx).AsTask().Wait(), "Create a table with SAS", (int)HttpStatusCode.NotFound); - - // Create the table. - await table.CreateAsync(); - - // Test invalid table operations - TestHelper.ExpectedException((ctx) => sasTable.DeleteAsync(null, ctx).AsTask().Wait(), "Delete a table with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasTable.GetPermissionsAsync(null, ctx).AsTask().Wait(), "Get ACL with SAS", (int)HttpStatusCode.NotFound); - TestHelper.ExpectedException((ctx) => sasTable.SetPermissionsAsync(new TablePermissions(), null, ctx).AsTask().Wait(), "Set ACL with SAS", (int)HttpStatusCode.NotFound); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Update SAS token - [TestMethod] - // [Description("Update table SAS.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableUpdateSasTestAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - - BaseEntity entity = new BaseEntity("PK", "RK"); - await table.ExecuteAsync(TableOperation.Insert(entity)); - - SharedAccessTablePolicy policy = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete, - }; - - string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null); - StorageCredentials creds = new StorageCredentials(sasToken); - CloudTable sasTable = new CloudTable(table.Uri, creds); - OperationContext context = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await sasTable.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK2")), null, context), - context, - "Try to insert an entity when SAS doesn't allow inserts", - HttpStatusCode.NotFound); - - await sasTable.ExecuteAsync(TableOperation.Delete(entity)); - - SharedAccessTablePolicy policy2 = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add, - }; - - string sasToken2 = table.GetSharedAccessSignature(policy2, null, null, null, null, null); - creds.UpdateSASToken(sasToken2); - - sasTable = new CloudTable(table.Uri, creds); - - await sasTable.ExecuteAsync(TableOperation.Insert(new BaseEntity("PK", "RK2"))); - - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - #endregion - - #region SasUri - [TestMethod] - // [Description("Use table SasUri.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableSasUriTestAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - CloudTable table = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N")); - - try - { - await table.CreateAsync(); - - BaseEntity entity = new BaseEntity("PK", "RK"); - BaseEntity entity1 = new BaseEntity("PK", "RK1"); - await table.ExecuteAsync(TableOperation.Insert(entity)); - await table.ExecuteAsync(TableOperation.Insert(entity1)); - - SharedAccessTablePolicy policy = new SharedAccessTablePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessTablePermissions.Delete, - }; - - string sasToken = table.GetSharedAccessSignature(policy, null, null, null, null, null); - StorageCredentials creds = new StorageCredentials(sasToken); - CloudStorageAccount sasAcc = new CloudStorageAccount(creds, new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint), new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint), new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint)); - CloudTableClient client = sasAcc.CreateCloudTableClient(); - - CloudTable sasTable = new CloudTable(client.Credentials.TransformUri(table.Uri)); - await sasTable.ExecuteAsync(TableOperation.Delete(entity)); - - CloudTable sasTable2 = new CloudTable(new Uri(table.Uri.ToString() + sasToken)); - await sasTable2.ExecuteAsync(TableOperation.Delete(entity1)); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - #endregion - - #region Test Helpers - internal static void AssertPermissionsEqual(TablePermissions permissions1, TablePermissions permissions2) - { - Assert.AreEqual(permissions1.SharedAccessPolicies.Count, permissions2.SharedAccessPolicies.Count); - - foreach (KeyValuePair pair in permissions1.SharedAccessPolicies) - { - SharedAccessTablePolicy policy1 = pair.Value; - SharedAccessTablePolicy policy2 = permissions2.SharedAccessPolicies[pair.Key]; - - Assert.IsNotNull(policy1); - Assert.IsNotNull(policy2); - - Assert.AreEqual(policy1.Permissions, policy2.Permissions); - if (policy1.SharedAccessStartTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessStartTime.Value - policy2.SharedAccessStartTime.Value).TotalSeconds) == 0); - } - - if (policy1.SharedAccessExpiryTime != null) - { - Assert.IsTrue(Math.Floor((policy1.SharedAccessExpiryTime.Value - policy2.SharedAccessExpiryTime.Value).TotalSeconds) == 0); - } - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableAnalyticsUnitTests.cs deleted file mode 100644 index 1479d01361b36..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableAnalyticsUnitTests.cs +++ /dev/null @@ -1,359 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public TableAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient client = GenerateCloudTableClient(); - startProperties = client.GetServicePropertiesAsync().AsTask().Result; - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - CloudTableClient client = GenerateCloudTableClient(); - client.SetServicePropertiesAsync(startProperties).AsTask().Wait(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - [TestMethod] - /// [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsRoundTripAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - /// [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsDisableAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsDefaultServiceVersionThrowsAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - await client.SetServicePropertiesAsync(props, null, ctx); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.Exception.Message, "XML specified is not syntactically valid."); - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - return; - } - - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - - [TestMethod] - /// [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsLoggingOperationsAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsMetricsLevelAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - /// [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsRetentionPoliciesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableBatchOperationTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableBatchOperationTest.cs deleted file mode 100644 index 5f01137c2f6d0..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableBatchOperationTest.cs +++ /dev/null @@ -1,1367 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableBatchOperationTest : TableTestBase - { - #region Locals + Ctors - public TableBatchOperationTest() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Insert - - [TestMethod] - //[Description("A test to check batch insert functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertAsync() - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 3; m++) - { - AddInsertToBatch(pk, batch); - } - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Add delete - batch.Delete(ent); - - IList results = await currentTable.ExecuteBatchAsync(batch); - - Assert.AreEqual(results.Count, 4); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - // delete - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - [TestMethod] - //[Description("A test to check batch insert functionality when entity already exists")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - - #region Insert Or Merge - - [TestMethod] - // [Description("TableBatch Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMergeAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrMerge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch2); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Insert Or Replace - - [TestMethod] - // [Description("TableOperation Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrReplaceAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrReplace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch2); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Delete - - [TestMethod] - // [Description("A test to check batch delete functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - TableBatchOperation batch = new TableBatchOperation(); - - // Add delete - batch.Delete(ent); - - // success - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NoContent); - - // fail - not found - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - [TestMethod] - // [Description("A test to check batch delete failure")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchDeleteFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // update entity - TableResult res = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEnt = res.Result as DynamicTableEntity; - retrievedEnt.Properties.Add("prop", new EntityProperty("var")); - await currentTable.ExecuteAsync(TableOperation.Replace(retrievedEnt)); - - // Attempt to delete with stale etag - TableBatchOperation batch = new TableBatchOperation(); - batch.Delete(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - #endregion - - #region Merge - - [TestMethod] - // [Description("TableBatch Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - // [Description("TableBatch Merge Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchMergeFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region Replace - - [TestMethod] - // [Description("TableBatch Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - // [Description("TableBatch Replace Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchReplaceFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - #endregion - - #region Batch With All Supported Operations - - [TestMethod] - //[Description("A test to check batch with all supported operations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchAllSupportedOperationsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - // insert - batch.Insert(GenerateRandomEnitity(pk)); - - // delete - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Delete(entity); - } - - // replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Replace(entity); - } - - // insert or replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.InsertOrReplace(entity); - } - - // merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Merge(entity); - } - - // insert or merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.InsertOrMerge(entity); - } - - IList results = await currentTable.ExecuteBatchAsync(batch); - - Assert.AreEqual(results.Count, 6); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - #endregion - - #region Retrieve - - [TestMethod] - // [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(pk); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt.Properties["String"], retrievedEntity.Properties["String"]); - Assert.AreEqual(sendEnt.Properties["Int64"], retrievedEntity.Properties["Int64"]); - Assert.AreEqual(sendEnt.Properties["Int64N"], retrievedEntity.Properties["Int64N"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitive"], retrievedEntity.Properties["LongPrimitive"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitiveN"], retrievedEntity.Properties["LongPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Int32"], retrievedEntity.Properties["Int32"]); - Assert.AreEqual(sendEnt.Properties["Int32N"], retrievedEntity.Properties["Int32N"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitive"], retrievedEntity.Properties["IntegerPrimitive"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitiveN"], retrievedEntity.Properties["IntegerPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Guid"], retrievedEntity.Properties["Guid"]); - Assert.AreEqual(sendEnt.Properties["GuidN"], retrievedEntity.Properties["GuidN"]); - Assert.AreEqual(sendEnt.Properties["Double"], retrievedEntity.Properties["Double"]); - Assert.AreEqual(sendEnt.Properties["DoubleN"], retrievedEntity.Properties["DoubleN"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitive"], retrievedEntity.Properties["DoublePrimitive"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitiveN"], retrievedEntity.Properties["DoublePrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["BinaryPrimitive"], retrievedEntity.Properties["BinaryPrimitive"]); - Assert.AreEqual(sendEnt.Properties["Binary"], retrievedEntity.Properties["Binary"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"], retrievedEntity.Properties["BoolPrimitive"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"], retrievedEntity.Properties["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Bool"], retrievedEntity.Properties["Bool"]); - Assert.AreEqual(sendEnt.Properties["BoolN"], retrievedEntity.Properties["BoolN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"], retrievedEntity.Properties["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffset"], retrievedEntity.Properties["DateTimeOffset"]); - Assert.AreEqual(sendEnt.Properties["DateTime"], retrievedEntity.Properties["DateTime"]); - Assert.AreEqual(sendEnt.Properties["DateTimeN"], retrievedEntity.Properties["DateTimeN"]); - } - - [TestMethod] - // [Description("A test to check batch retrieve with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveWithResolverAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver); - - // not found - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)results.First().Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt.Properties["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - #endregion - - #region Empty Keys Test - - [TestMethod] - // [Description("TableBatchOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOperationsWithEmptyKeysAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity - TableBatchOperation retrieveBatch = new TableBatchOperation(); - retrieveBatch.Retrieve(ent.PartitionKey, ent.RowKey); - TableResult result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - batch = new TableBatchOperation(); - batch.Delete(retrievedEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - Assert.IsNull(result.Result); - } - - #endregion - - #region Bulk insert - - [TestMethod] - // [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert1() - { - await InsertAndDeleteBatchWithNEntities(1); - } - - [TestMethod] - // [Description("A test to peform batch insert and delete with batch size of 10")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert10() - { - await InsertAndDeleteBatchWithNEntities(10); - } - - - [TestMethod] - // [Description("A test to peform batch insert and delete with batch size of 99")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert99() - { - await InsertAndDeleteBatchWithNEntities(99); - } - - [TestMethod] - // [Description("A test to peform batch insert and delete with batch size of 100")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert100() - { - await InsertAndDeleteBatchWithNEntities(100); - } - - private async Task InsertAndDeleteBatchWithNEntities(int n) - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < n; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - IList results = await currentTable.ExecuteBatchAsync(batch); - - TableBatchOperation delBatch = new TableBatchOperation(); - - foreach (TableResult res in results) - { - delBatch.Delete((ITableEntity)res.Result); - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.Created); - } - - IList delResults = await currentTable.ExecuteBatchAsync(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Bulk Upsert - - [TestMethod] - // [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge1() - { - await InsertOrMergeBatchWithNEntities(1); - } - - [TestMethod] - // [Description("A test to peform batch InsertOrMerge with batch size of 10")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge10() - { - await InsertOrMergeBatchWithNEntities(10); - } - - - [TestMethod] - // [Description("A test to peform batch InsertOrMerge with batch size of 99")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge99() - { - await InsertOrMergeBatchWithNEntities(99); - } - - [TestMethod] - // [Description("A test to peform batch InsertOrMerge with batch size of 100")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge100() - { - await InsertOrMergeBatchWithNEntities(100); - } - - private async Task InsertOrMergeBatchWithNEntities(int n) - { - string pk = Guid.NewGuid().ToString(); - - TableBatchOperation insertBatch = new TableBatchOperation(); - TableBatchOperation mergeBatch = new TableBatchOperation(); - TableBatchOperation delBatch = new TableBatchOperation(); - - for (int m = 0; m < n; m++) - { - insertBatch.InsertOrMerge(GenerateRandomEnitity(pk)); - } - - IList results = await currentTable.ExecuteBatchAsync(insertBatch); - foreach (TableResult res in results) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // update entity and add to merge batch - DynamicTableEntity ent = res.Result as DynamicTableEntity; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - mergeBatch.InsertOrMerge(ent); - - } - - // execute insertOrMerge batch, this time entities exist - IList mergeResults = await currentTable.ExecuteBatchAsync(mergeBatch); - - foreach (TableResult res in mergeResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // Add to delete batch - delBatch.Delete((ITableEntity)res.Result); - } - - IList delResults = await currentTable.ExecuteBatchAsync(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Boundary Conditions - - [TestMethod] - //[Description("Ensure that adding null to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddNullShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - try - { - batch.Add(null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - //[Description("Ensure that adding multiple queries to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddMultiQueryShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve("foo", "bar"); - try - { - batch.Retrieve("foo", "bar2"); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - // [Description("Ensure that a batch that contains multiple operations on the same entity fails")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchWithMultipleOperationsOnSameEntityShouldFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ITableEntity first = GenerateRandomEnitity(pk); - batch.Insert(first); - - for (int m = 0; m < 99; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - // Insert Duplicate entity - batch.Insert(first); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, new string[] { "99:One of the request inputs is not valid." }, false); - } - } - - [TestMethod] - //[Description("Ensure that a batch with over 100 entities will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOver100EntitiesShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < 101; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - [TestMethod] - //[Description("Ensure that a batch with entity over 1 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchEntityOver1MBShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity ent = GenerateRandomEnitity(pk); - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - - [TestMethod] - //[Description("Ensure that a batch over 4 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOver4MBShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 65; m++) - { - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - // Maximum Entity size is 64KB - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[64 * 1024])); - batch.Insert(ent); - } - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "ContentLengthExceeded" }, "The content length for the requested operation has exceeded the limit (4MB)."); - } - } - - [TestMethod] - //[Description("Ensure that a query and one more operation will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddQueryAndOneMoreOperationShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - - try - { - batch.Add(TableOperation.Retrieve("foo", "bar")); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Add(TableOperation.Retrieve("foo", "bar")); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - - try - { - batch.Add(TableOperation.Retrieve("foo", "bar")); - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Insert(0, TableOperation.Retrieve("foo", "bar")); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - } - - [TestMethod] - //[Description("Ensure that empty batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchEmptyBatchShouldThrowAsync() - { - TableBatchOperation batch = new TableBatchOperation(); - await TestHelper.ExpectedExceptionAsync( - async () => await currentTable.ExecuteBatchAsync(batch), - "Empty batch operation should fail"); - } - - [TestMethod] - //[Description("Ensure that a given batch only allows entities with the same partitionkey")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchLockToPartitionKey() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - // should reset pk lock - batch.RemoveAt(0); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - } - catch (ArgumentException) - { - Assert.Fail(); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - //[Description("Ensure that a batch with an entity property over 255 chars will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchWithPropertyOver255CharsShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - string propName = new string('a', 256); - - DynamicTableEntity ent = new DynamicTableEntity("foo", "bar"); - ent.Properties.Add(propName, new EntityProperty("propbar")); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "PropertyNameTooLong" }, "The property name exceeds the maximum allowed length (255)."); - } - } - - #endregion - - #region Helpers - - private static void AddInsertToBatch(string pk, TableBatchOperation batch) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - private static DynamicTableEntity GenerateRandomEnitity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEntitySerializationTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEntitySerializationTests.cs deleted file mode 100644 index 0c9be21988a11..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEntitySerializationTests.cs +++ /dev/null @@ -1,234 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableEntitySerializationTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableEntitySerializationTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - [TestMethod] - //[Description("A test checks basic function Reflection Serializer")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ReflectionBasedSerializationTest() - { - ComplexEntity ent = new ComplexEntity(); - ComplexEntity secondEnt = new ComplexEntity(); - secondEnt.ReadEntity(ent.WriteEntity(null), null); - ComplexEntity.AssertEquality(ent, secondEnt); - } - - [TestMethod] - //[Description("A test checks basic function Reflection Serializer")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void EntityPropertyTests() - { - Random rand = new Random(); - - // Binary - byte[] bytes = new byte[1024]; - rand.NextBytes(bytes); - - // Ctor - EntityProperty binProp = EntityProperty.GeneratePropertyForByteArray(bytes); - Assert.AreEqual(binProp.BinaryValue, bytes); - - // Setter - byte[] bytes2 = new byte[1024]; - rand.NextBytes(bytes2); - binProp.BinaryValue = bytes2; - Assert.AreEqual(binProp.BinaryValue, bytes2); - - // Null - binProp.BinaryValue = null; - Assert.AreEqual(binProp.BinaryValue, null); - - // bool - bool boolVal = true; - - // Ctor - EntityProperty boolProp = EntityProperty.GeneratePropertyForBool(boolVal); - Assert.AreEqual(boolProp.BooleanValue, boolVal); - - // Setter - bool boolVal2 = true; - boolProp.BooleanValue = boolVal2; - Assert.AreEqual(boolProp.BooleanValue, boolVal2); - - // DateTimeOffset - DateTimeOffset dto = DateTimeOffset.Now; - - // Ctor - EntityProperty dtoProp = EntityProperty.GeneratePropertyForDateTimeOffset(dto); - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto); - - // Setter - DateTimeOffset dto2 = DateTimeOffset.UtcNow; - dtoProp.DateTimeOffsetValue = dto2; - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto2); - - // Null - DateTimeOffset? dto3 = (DateTimeOffset?)null; - dtoProp.DateTimeOffsetValue = dto3; - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto3); - - // double - double doubleVal = 1234.4564; - - // Ctor - EntityProperty doubleProp = EntityProperty.GeneratePropertyForDouble(doubleVal); - Assert.AreEqual(doubleProp.DoubleValue, doubleVal); - - // Setter - double doubleVal2 = 8979654.35454; - doubleProp.DoubleValue = doubleVal2; - Assert.AreEqual(doubleProp.DoubleValue, doubleVal2); - - // Guid - Guid guidVal = new Guid(); - - // Ctor - EntityProperty guidProp = EntityProperty.GeneratePropertyForGuid(guidVal); - Assert.AreEqual(guidProp.GuidValue, guidVal); - - // Setter - Guid guidVal2 = new Guid(); - guidProp.GuidValue = guidVal2; - Assert.AreEqual(guidProp.GuidValue, guidVal2); - - // int - int intVal = 1234; - - // Ctor - EntityProperty intProp = EntityProperty.GeneratePropertyForInt(intVal); - Assert.AreEqual(intProp.Int32Value, intVal); - - // Setter - int intVal2 = 8979654; - intProp.Int32Value = intVal2; - Assert.AreEqual(intProp.Int32Value, intVal2); - - // long - long longVal = 123456789012; - - // Ctor - EntityProperty longProp = EntityProperty.GeneratePropertyForLong(longVal); - Assert.AreEqual(longProp.Int64Value, longVal); - - // Setter - long longVal2 = 56789012345; - longProp.Int64Value = longVal2; - Assert.AreEqual(longProp.Int64Value, longVal2); - - // string - string string1 = "abcdefghijklmnop"; - - // Ctor - EntityProperty stringProp = EntityProperty.GeneratePropertyForString(string1); - Assert.AreEqual(stringProp.StringValue, string1); - - // Setter - string string2 = "1234567890"; - stringProp.StringValue = string2; - Assert.AreEqual(stringProp.StringValue, string2); - - // Null - string string3 = null; - stringProp.StringValue = string3; - Assert.AreEqual(stringProp.StringValue, string3); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEscapingTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEscapingTests.cs deleted file mode 100644 index 68d88e3446276..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableEscapingTests.cs +++ /dev/null @@ -1,369 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableEscapingTests : TableTestBase - { - #region Locals + Ctors - public TableEscapingTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - [TestMethod] - //[Description("Escaping test for whitespace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingWhiteSpaceOnlyAsync() - { - await this.DoEscapeTestAsync(" ", false, true); - } - - [TestMethod] - //[Description("Escaping test for whitespace in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingWhiteSpaceOnlyInBatchAsync() - { - await this.DoEscapeTestAsync(" ", true, true); - } - - [TestMethod] - //[Description("Escaping test for EmptyString")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingEmptyStringAsync() - { - await this.DoEscapeTestAsync("", false, true); - } - - [TestMethod] - //[Description("Escaping test for EmptyString in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingEmptyStringOnlyInBatchAsync() - { - await this.DoEscapeTestAsync("", true, true); - } - - [TestMethod] - //[Description("Escaping test for RandomChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingRandomCharsAsync() - { - await this.DoEscapeTestAsync("!$'\"()*+,;=", false, false); - } - - [TestMethod] - //[Description("Escaping test for RandomChars in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingRandomCharsInBatchAsync() - { - await this.DoEscapeTestAsync("!$'\"()*+,;=", true, false); - } - - [TestMethod] - //[Description("Escaping test for Percent25")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingPercent25Async() - { - await this.DoEscapeTestAsync("foo%25", false, true); - } - - [TestMethod] - //[Description("Escaping test for Percent25 in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingPercent25InBatchAsync() - { - await this.DoEscapeTestAsync("foo%25", true, true); - } - - [TestMethod] - //[Description("Escaping test for SpecialChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingSpecialCharsAsync() - { - await this.DoEscapeTestAsync("\\ // @ ? ", false, false); - await this.DoEscapeTestAsync("", false, false); - await this.DoEscapeTestAsync("", false, false); - await this.DoEscapeTestAsync("!<", false, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("!<", true, false); - await this.DoEscapeTestAsync(" -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableOperationUnitTests : TableTestBase - { - #region Locals + Ctors - public TableOperationUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - // [ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - // [ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Insert - - [TestMethod] - // [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - } - - [TestMethod] - // [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertSingleQuoteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "partition'key", RowKey = "row'key" }; - ent.Properties.Add("stringprop", new EntityProperty("string'value")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(ent)); - - TableQuery query = new TableQuery().Where(TableQuery.CombineFilters( - (TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ent.PartitionKey)), - TableOperators.And, - (TableQuery.GenerateFilterCondition("stringprop", QueryComparisons.Equal, ent.Properties["stringprop"].StringValue)))); - - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); - - foreach (DynamicTableEntity retrievedEntity in seg) - { - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties["stringprop"].StringValue, retrievedEntity.Properties["stringprop"].StringValue); - } - - ComplexEntity complexEntity = new ComplexEntity() { PartitionKey = "partition'key", RowKey = "row'key" }; - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(complexEntity)); - - TableQuery query2 = new TableQuery().Where(TableQuery.CombineFilters( - (TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ent.PartitionKey)), - TableOperators.And, - (TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, ent.RowKey)))); - - TableQuerySegment seg2 = await currentTable.ExecuteQuerySegmentedAsync(query2, null); - foreach (ComplexEntity retrievedComplexEntity in seg2) - { - Assert.IsNotNull(retrievedComplexEntity); - Assert.AreEqual(ent.PartitionKey, retrievedComplexEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedComplexEntity.RowKey); - } - } - - [TestMethod] - // [Description("TableOperation Insert Conflict")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertConflictAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - OperationContext opContext = new OperationContext(); - - // Attempt Insert Conflict Entity - DynamicTableEntity conflictEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - try - { - await currentTable.ExecuteAsync(TableOperation.Insert(conflictEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - - #endregion - - #region Insert Or Merge - - [TestMethod] - // [Description("TableOperation Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOrMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Insert Or Replace - - [TestMethod] - // [Description("TableOperation Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOrReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Delete - - [TestMethod] - // [Description("TableOperation Delete")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNotNull(result.Result); - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(ent)); - - // Retrieve Entity - TableResult result2 = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - [TestMethod] - // [Description("TableOperation Delete Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationDeleteFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - OperationContext opContext = new OperationContext(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.ETag = "*"; - - try - { - await currentTable.ExecuteAsync(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - - - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - retrievedEntity.Properties["foo"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(retrievedEntity)); - - try - { - opContext = new OperationContext(); - // Now delete old reference with stale etag and validate exception - await currentTable.ExecuteAsync(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - - #endregion - - #region Merge - - [TestMethod] - // [Description("TableOperation Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - // [Description("TableOperation Merge Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationMergeFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region Replace - - [TestMethod] - // [Description("TableOperation Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - // [Description("TableOperation Replace Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationReplaceFail() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - #endregion - - #region Retrieve - - [TestMethod] - // [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - // not found - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt.Properties["String"], retrievedEntity.Properties["String"]); - Assert.AreEqual(sendEnt.Properties["Int64"], retrievedEntity.Properties["Int64"]); - Assert.AreEqual(sendEnt.Properties["Int64N"], retrievedEntity.Properties["Int64N"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitive"], retrievedEntity.Properties["LongPrimitive"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitiveN"], retrievedEntity.Properties["LongPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Int32"], retrievedEntity.Properties["Int32"]); - Assert.AreEqual(sendEnt.Properties["Int32N"], retrievedEntity.Properties["Int32N"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitive"], retrievedEntity.Properties["IntegerPrimitive"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitiveN"], retrievedEntity.Properties["IntegerPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Guid"], retrievedEntity.Properties["Guid"]); - Assert.AreEqual(sendEnt.Properties["GuidN"], retrievedEntity.Properties["GuidN"]); - Assert.AreEqual(sendEnt.Properties["Double"], retrievedEntity.Properties["Double"]); - Assert.AreEqual(sendEnt.Properties["DoubleN"], retrievedEntity.Properties["DoubleN"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitive"], retrievedEntity.Properties["DoublePrimitive"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitiveN"], retrievedEntity.Properties["DoublePrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["BinaryPrimitive"], retrievedEntity.Properties["BinaryPrimitive"]); - Assert.AreEqual(sendEnt.Properties["Binary"], retrievedEntity.Properties["Binary"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"], retrievedEntity.Properties["BoolPrimitive"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"], retrievedEntity.Properties["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Bool"], retrievedEntity.Properties["Bool"]); - Assert.AreEqual(sendEnt.Properties["BoolN"], retrievedEntity.Properties["BoolN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"], retrievedEntity.Properties["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffset"], retrievedEntity.Properties["DateTimeOffset"]); - Assert.AreEqual(sendEnt.Properties["DateTime"], retrievedEntity.Properties["DateTime"]); - Assert.AreEqual(sendEnt.Properties["DateTimeN"], retrievedEntity.Properties["DateTimeN"]); - } - - - [TestMethod] - // [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveWithResolverAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.PartitionKey = Guid.NewGuid().ToString(); - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - // not found - TableResult result = await currentTable.ExecuteAsync(TableOperationFactory.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - result = await currentTable.ExecuteAsync(TableOperationFactory.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)result.Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt.Properties["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - - [TestMethod] - // [Description("A test to check ignore property attribute while serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveWithIgnoreAttributeWriteAsync() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - IgnoreEntity sendEnt = new IgnoreEntity(pk, rk); - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = true; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = DateTimeOffset.Now.AddMinutes(1); - - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("BoolPrimitiveNull")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("Bool")); - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.Properties["BoolPrimitive"].BooleanValue); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.Properties["BoolPrimitiveN"].BooleanValue); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.Properties["BoolN"].BooleanValue); - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffset")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffsetNull")); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.Properties["DateTimeOffsetN"].DateTimeOffsetValue); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.Properties["DateTime"].DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.Properties["DateTimeN"].DateTime); - } - - [TestMethod] - // [Description("A test to check ignore property attribute while de-serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveWithIgnoreAttributeReadAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.Properties.Add("Bool", new EntityProperty(true)); - sendEnt.Properties.Add("BoolN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolNull", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitive", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveNull", new EntityProperty(true)); - sendEnt.Properties.Add("DateTime", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeN", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeNull", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffset", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetN", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetNull", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, pk)); - IEnumerable result = await currentTable.ExecuteQuerySegmentedAsync(query, null); - IgnoreEntity retrievedEntity = result.ToList().First() as IgnoreEntity; - - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"].BooleanValue, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"].BooleanValue, retrievedEntity.BoolPrimitiveN); - Assert.AreNotEqual(sendEnt.Properties["BoolPrimitiveNull"].BooleanValue, retrievedEntity.BoolPrimitiveNull); - Assert.AreNotEqual(sendEnt.Properties["Bool"].BooleanValue, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.Properties["BoolN"].BooleanValue, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.Properties["BoolNull"].BooleanValue, retrievedEntity.BoolNull); - - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffset"].DateTimeOffsetValue, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetN); - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffsetNull"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetNull); - Assert.IsNull(retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.Properties["DateTime"].DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.Properties["DateTimeN"].DateTime, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.Properties["DateTimeNull"].DateTime, retrievedEntity.DateTimeNull); - } - - [TestMethod] - // [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveSyncWithIgnoreAttributesAsync() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - IgnoreEntity sendEnt = new IgnoreEntity(pk, rk); - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = true; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = DateTimeOffset.Now.AddMinutes(1); - - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, pk)); - - IEnumerable result = await currentTable.ExecuteQuerySegmentedAsync(query, null); - IgnoreEntity retrievedEntity = result.ToList().First() as IgnoreEntity; - - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.BoolPrimitiveN); - Assert.AreNotEqual(sendEnt.BoolPrimitiveNull, retrievedEntity.BoolPrimitiveNull); - Assert.AreNotEqual(sendEnt.Bool, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.BoolNull, retrievedEntity.BoolNull); - - Assert.AreNotEqual(sendEnt.DateTimeOffset, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.DateTimeOffsetN); - Assert.AreNotEqual(sendEnt.DateTimeOffsetNull, retrievedEntity.DateTimeOffsetNull); - Assert.IsNull(retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.DateTimeNull, retrievedEntity.DateTimeNull); - } - #endregion - - #region Empty Keys Test - - [TestMethod] - // [Description("TableOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationsWithEmptyKeysAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(retrievedEntity)); - - // Retrieve Entity - TableResult result2 = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - #endregion - - #region Insert Negative Tests - - [TestMethod] - // [Description("TableOperation Insert Entity over 1 MB")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOver1MBAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("largeprop", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - - OperationContext opContext = new OperationContext(); - try - { - - await currentTable.ExecuteAsync(TableOperation.Insert(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - #endregion - - #region Serialization/De-serialization tests - - [TestMethod] - // [Description("TableOperations with entities not derived from TableEntity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableOpsWithNonDerivedEntitiesAsync() - { - List DTOObjects = new List(new ShapeEntity[3] { new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "square", 4, 4), new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "rectangle", 5, 4), new ShapeEntity(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "parallelogram", 6, 4) }); - - IEnumerable> azureObjects = DTOObjects.Select(ent => new POCOAdapter(ent, ent.PartitionKey, ent.RowKey)); - - int i = 0; - foreach (POCOAdapter azureObject in azureObjects) - { - IDictionary properties = azureObject.WriteEntity(null); - Assert.AreEqual(3, properties.Count); - Assert.AreEqual(DTOObjects.ElementAt(i).Name, properties["Name"].StringValue); - Assert.AreEqual(DTOObjects.ElementAt(i).Length, properties["Length"].Int32Value); - Assert.AreEqual(DTOObjects.ElementAt(i).Breadth, properties["Breadth"].Int32Value); - - OperationContext context = new OperationContext(); - POCOAdapter ent = new POCOAdapter(new ShapeEntity()); - ent.ReadEntity(properties, context); - Assert.AreEqual(properties["Name"].StringValue, ent.Shape.Name); - Assert.AreEqual(properties["Length"].Int32Value, ent.Shape.Length); - Assert.AreEqual(properties["Breadth"].Int32Value, ent.Shape.Breadth); - i++; - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryGenericTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryGenericTests.cs deleted file mode 100644 index 4b1a2b4c7dc82..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryGenericTests.cs +++ /dev/null @@ -1,538 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryGenericTests : TableTestBase - { - #region Locals + Ctors - public TableQueryGenericTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - BaseEntity ent = GenerateRandomEnitity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - currentTable.ExecuteBatchAsync(batch).AsTask().Wait(); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Unit Tests - - [TestMethod] - // [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryBasicAsync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); - - foreach (BaseEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - // [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryWithContinuationAsync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - - int count = 0; - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); - - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - // [Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithFilter() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - ent.Validate(); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - // [Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryProjection() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - // [Description("Basic with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericWithResolver() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - foreach (string ent in ExecuteQuery(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - // [Description("Basic resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryResolverWithDynamic() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - foreach (string ent in ExecuteQueryWithResolver(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - foreach (BaseEntity ent in ExecuteQueryWithResolver(currentTable, query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - // [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryOnSupportedTypesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ComplexEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - batch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.LongPrimitive), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Double), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Int32), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.DateTimeOffset), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.BinaryPrimitive), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - #endregion - - #region Negative Tests - - [TestMethod] - // [Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - // [Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static List ExecuteQuery(CloudTable table, TableQuery query) where T: ITableEntity, new() - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, currSeg != null ? currSeg.ContinuationToken : null).AsTask()); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static List ExecuteQueryWithResolver(CloudTable table, TableQuery query, EntityResolver resolver) - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, resolver, currSeg != null ? currSeg.ContinuationToken : null).AsTask()); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - - } - - return retList; - } - - private static List ExecuteQuery(CloudTable table, TableQuery query, EntityResolver resolver) where T : ITableEntity, new() - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, resolver, currSeg != null ? currSeg.ContinuationToken : null).AsTask()); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, ExecuteQuery(table, new TableQuery().Where(filter)).Count()); - } - - private static BaseEntity GenerateRandomEnitity(string pk) - { - BaseEntity ent = new BaseEntity(); - ent.Populate(); - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryTests.cs deleted file mode 100644 index 6ed93c4b4cf55..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableQueryTests.cs +++ /dev/null @@ -1,613 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; -using Windows.Globalization; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableQueryTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static void MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - currentTable.CreateIfNotExistsAsync().AsTask().Wait(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - DynamicTableEntity ent = GenerateRandomEntity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - currentTable.ExecuteBatchAsync(batch).AsTask().Wait(); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static void MyClassCleanup() - { - currentTable.DeleteIfExistsAsync().AsTask().Wait(); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.TableBufferManager != null) - { - TestBase.TableBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.TableBufferManager != null) - { - Assert.AreEqual(0, TestBase.TableBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Unit Tests - - [TestMethod] - //[Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryBasicAsync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - //[Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryWithContinuationAsync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - //[Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithFilterAsync() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.AreEqual(ent.Properties["foo"].StringValue, "bar"); - - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - //[Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryProjectionAsync() - { - TableQuery query = new TableQuery().Select(new List() { "a", "c" }); - - foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.Properties["a"].StringValue, "a"); - Assert.IsFalse(ent.Properties.ContainsKey("b")); - Assert.AreEqual(ent.Properties["c"].StringValue, "c"); - Assert.IsFalse(ent.Properties.ContainsKey("d")); - } - } - - [TestMethod] - //[Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryOnSupportedTypesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.Properties["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - } - finally - { - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - //[Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRegionalQueryOnSupportedTypesAsync() - { - string currentPrimaryLanguage = ApplicationLanguages.PrimaryLanguageOverride; - ApplicationLanguages.PrimaryLanguageOverride = "tr"; - - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.Properties["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - } - finally - { - ApplicationLanguages.PrimaryLanguageOverride = currentPrimaryLanguage; - table.DeleteIfExistsAsync().AsTask().Wait(); - } - } - - [TestMethod] - // [Description("A test to validate querying with an empty value")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryEmptyValueAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - // Setup - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey"); - dynEnt.Properties.Add("A", new EntityProperty(string.Empty)); - await table.ExecuteAsync(TableOperation.Insert(dynEnt)); - - // 1. Filter on String - List results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); - Assert.AreEqual(1, results.Count); - - List pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); - Assert.AreEqual(1, pocoresults.Count); - } - #endregion - - #region Negative Tests - - [TestMethod] - //[Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - //[Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static List ExecuteQuery(CloudTable table, TableQuery query) - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, currSeg != null ? currSeg.ContinuationToken : null).AsTask()); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, ExecuteQuery(table, new TableQuery().Where(filter)).Count()); - } - - private static DynamicTableEntity GenerateRandomEntity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("a", new EntityProperty("a")); - ent.Properties.Add("b", new EntityProperty("b")); - ent.Properties.Add("c", new EntityProperty("c")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableTestBase.cs deleted file mode 100644 index 118bd184df450..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/Table/TableTestBase.cs +++ /dev/null @@ -1,58 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - public class TableTestBase : TestBase - { - public static string GenerateRandomTableName() - { - return "tbl" + Guid.NewGuid().ToString().Replace("-", ""); - } - - /* - public static async void CleanupTables() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - try - { - IEnumerable tables = tableClient.ListTables(); - foreach (CloudTable table in tables) - { - await table.DeleteAsync(); - } - } - catch (Exception) - { - } - }*/ - - public static string GenerateRandomStringFromCharset(int TableNameLength, string LegalChars, Random rand) - { - StringBuilder retString = new StringBuilder(); - for (int n = 0; n < TableNameLength; n++) - { - retString.Append(LegalChars[rand.Next(LegalChars.Length - 1)]); - } - - return retString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestBase.cs deleted file mode 100644 index 23ae1d8a3a744..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestBase.cs +++ /dev/null @@ -1,51 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Xml.Linq; -using Windows.Data.Xml.Dom; -using Windows.Storage; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestBase - { - static TestBase() - { - StorageFile xmlFile = Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(TestConfigurations.DefaultTestConfigFilePath).AsTask().Result; - XmlDocument xmlDoc = XmlDocument.LoadFromFileAsync(xmlFile).AsTask().Result; - - XDocument doc = XDocument.Parse(xmlDoc.GetXml()); - TestConfigurations = TestConfigurations.ReadFromXml(doc); - - foreach (TenantConfiguration tenant in TestConfigurations.TenantConfigurations) - { - if (tenant.TenantName == TestConfigurations.TargetTenantName) - { - TargetTenantConfig = tenant; - break; - } - } - - StorageCredentials = new StorageCredentials(TestBase.TargetTenantConfig.AccountName, - TestBase.TargetTenantConfig.AccountKey); - - CurrentTenantType = TargetTenantConfig.TenantType; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestHelper.cs b/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestHelper.cs deleted file mode 100644 index 4660b1cf96d4c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/RT/TestHelper.cs +++ /dev/null @@ -1,115 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestHelper - { - /// - /// Compares the streams from the current position to the end. - /// - internal static async Task AssertStreamsAreEqualAsync(IInputStream src, IInputStream dst) - { - Stream srcAsStream = src.AsStreamForRead(); - Stream dstAsStream = dst.AsStreamForRead(); - - byte[] srcBuffer = new byte[64 * 1024]; - int srcRead; - - byte[] dstBuffer = new byte[64 * 1024]; - int dstRead; - - do - { - srcRead = await srcAsStream.ReadAsync(srcBuffer, 0, srcBuffer.Length); - dstRead = await dstAsStream.ReadAsync(dstBuffer, 0, dstBuffer.Length); - - Assert.AreEqual(srcRead, dstRead); - - for (int i = 0; i < srcRead; i++) - { - Assert.AreEqual(srcBuffer[i], dstBuffer[i]); - } - } - while (srcRead > 0); - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static async Task ExpectedExceptionAsync(Func operation, string operationDescription) - where T : Exception - { - try - { - await operation(); - } - catch (T e) - { - return e; - } - catch (Exception ex) - { - T e = ex as T; // Test framework changes the value under debugger - if (e != null) - { - return e; - } - Assert.Fail("Invalid exception {0} for operation: {1}", ex.GetType(), operationDescription); - } - - Assert.Fail("No exception received while while expecting {0}: {1}", typeof(T).ToString(), operationDescription); - return null; - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static async Task ExpectedExceptionAsync(Func operation, OperationContext operationContext, string operationDescription, HttpStatusCode expectedStatusCode, string requestErrorCode = null) - { - try - { - await operation(); - } - catch (Exception) - { - Assert.AreEqual((int)expectedStatusCode, operationContext.LastResult.HttpStatusCode, "Http status code is unexpected."); - if (!string.IsNullOrEmpty(requestErrorCode)) - { - Assert.IsNotNull(operationContext.LastResult.ExtendedErrorInformation); - Assert.AreEqual(requestErrorCode, operationContext.LastResult.ExtendedErrorInformation.ErrorCode); - } - return; - } - - Assert.Fail("No exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml b/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml deleted file mode 100644 index c17a7c18a18be..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml.cs deleted file mode 100644 index a579126a27cda..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/App.xaml.cs +++ /dev/null @@ -1,194 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.Phone.Controls; -using Microsoft.Phone.Shell; -using Microsoft.WindowsAzure.Storage.Resources; -using System; -using System.Diagnostics; -using System.Windows; -using System.Windows.Markup; -using System.Windows.Navigation; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class App : Application - { - /// - /// Provides easy access to the root frame of the Phone Application. - /// - /// The root frame of the Phone Application. - public static PhoneApplicationFrame RootFrame { get; private set; } - - /// - /// Constructor for the Application object. - /// - public App() - { - // Global handler for uncaught exceptions. - UnhandledException += Application_UnhandledException; - - // Standard XAML initialization - InitializeComponent(); - - // Phone-specific initialization - InitializePhoneApplication(); - - // Language display initialization - InitializeLanguage(); - } - - // Code to execute if a navigation fails - private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) - { - if (Debugger.IsAttached) - { - // A navigation has failed; break into the debugger - Debugger.Break(); - } - } - - // Code to execute on Unhandled Exceptions - private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) - { - if (Debugger.IsAttached) - { - // An unhandled exception has occurred; break into the debugger - Debugger.Break(); - } - } - - #region Phone application initialization - - // Avoid double-initialization - private bool phoneApplicationInitialized = false; - - // Do not add any additional code to this method - private void InitializePhoneApplication() - { - if (phoneApplicationInitialized) - return; - - // Create the frame but don't set it as RootVisual yet; this allows the splash - // screen to remain active until the application is ready to render. - RootFrame = new PhoneApplicationFrame(); - RootFrame.Navigated += CompleteInitializePhoneApplication; - - // Handle navigation failures - RootFrame.NavigationFailed += RootFrame_NavigationFailed; - - // Handle reset requests for clearing the backstack - RootFrame.Navigated += CheckForResetNavigation; - - // Ensure we don't initialize again - phoneApplicationInitialized = true; - } - - // Do not add any additional code to this method - private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e) - { - // Set the root visual to allow the application to render - if (RootVisual != RootFrame) - RootVisual = RootFrame; - - // Remove this handler since it is no longer needed - RootFrame.Navigated -= CompleteInitializePhoneApplication; - } - - private void CheckForResetNavigation(object sender, NavigationEventArgs e) - { - // If the app has received a 'reset' navigation, then we need to check - // on the next navigation to see if the page stack should be reset - if (e.NavigationMode == NavigationMode.Reset) - RootFrame.Navigated += ClearBackStackAfterReset; - } - - private void ClearBackStackAfterReset(object sender, NavigationEventArgs e) - { - // Unregister the event so it doesn't get called again - RootFrame.Navigated -= ClearBackStackAfterReset; - - // Only clear the stack for 'new' (forward) and 'refresh' navigations - if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh) - return; - - // For UI consistency, clear the entire page stack - while (RootFrame.RemoveBackEntry() != null) - { - ; // do nothing - } - } - - #endregion - - // Initialize the app's font and flow direction as defined in its localized resource strings. - // - // To ensure that the font of your application is aligned with its supported languages and that the - // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage - // and ResourceFlowDirection should be initialized in each resx file to match these values with that - // file's culture. For example: - // - // AppResources.es-ES.resx - // ResourceLanguage's value should be "es-ES" - // ResourceFlowDirection's value should be "LeftToRight" - // - // AppResources.ar-SA.resx - // ResourceLanguage's value should be "ar-SA" - // ResourceFlowDirection's value should be "RightToLeft" - // - // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072. - // - private void InitializeLanguage() - { - try - { - // Set the font to match the display language defined by the - // ResourceLanguage resource string for each supported language. - // - // Fall back to the font of the neutral language if the Display - // language of the phone is not supported. - // - // If a compiler error is hit then ResourceLanguage is missing from - // the resource file. - RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage); - - // Set the FlowDirection of all elements under the root frame based - // on the ResourceFlowDirection resource string for each - // supported language. - // - // If a compiler error is hit then ResourceFlowDirection is missing from - // the resource file. - FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection); - RootFrame.FlowDirection = flow; - } - catch - { - // If an exception is caught here it is most likely due to either - // ResourceLangauge not being correctly set to a supported language - // code or ResourceFlowDirection is set to a value other than LeftToRight - // or RightToLeft. - - if (Debugger.IsAttached) - { - Debugger.Break(); - } - - throw; - } - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/AlignmentGrid.png b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/AlignmentGrid.png deleted file mode 100644 index f7d2e97804e45..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/AlignmentGrid.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/ApplicationIcon.png b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/ApplicationIcon.png deleted file mode 100644 index 7d95d4e0810f4..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/ApplicationIcon.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileLarge.png b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileLarge.png deleted file mode 100644 index e0c59ac014604..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileLarge.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileMedium.png b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileMedium.png deleted file mode 100644 index e93b89d600641..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileMedium.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileSmall.png b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileSmall.png deleted file mode 100644 index 550b1b5e8d003..0000000000000 Binary files a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Assets/Tiles/FlipCycleTileSmall.png and /dev/null differ diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobAnalyticsUnitTests.cs deleted file mode 100644 index d1238f2a8f3d1..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobAnalyticsUnitTests.cs +++ /dev/null @@ -1,364 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public BlobAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudBlobClient client = GenerateCloudBlobClient(); - startProperties = await client.GetServicePropertiesAsync(); - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - CloudBlobClient client = GenerateCloudBlobClient(); - await client.SetServicePropertiesAsync(startProperties); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - [TestMethod] - [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsRoundTripAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsDisableAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Default Service Version")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsDefaultServiceVersionAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - props.DefaultServiceVersion = "2009-09-19"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = "2011-08-18"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = "2012-02-12"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - props.DefaultServiceVersion = null; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsLoggingOperationsAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsMetricsLevelAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobTestAnalyticsRetentionPoliciesAsync() - { - CloudBlobClient client = GenerateCloudBlobClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobCancellationUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobCancellationUnitTests.cs deleted file mode 100644 index 85391f7fba999..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobCancellationUnitTests.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Windows.Foundation; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobCancellationUnitTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - /*[TestMethod] - [Description("Cancel blob download to stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToStreamCancelAsync() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(originalBlob); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - OperationContext operationContext = new OperationContext(); - Task task = blob.DownloadToStreamAsync(downloadedBlob, null, null, operationContext); - await Task.Delay(100); - task.Cancel(); - try - { - await action; - } - catch (Exception) - { - Assert.AreEqual(operationContext.LastResult.Exception.Message, "A task was canceled."); - Assert.AreEqual(operationContext.LastResult.HttpStatusCode, 306); - //Assert.AreEqual(operationContext.LastResult.HttpStatusMessage, "Unused"); - } - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Cancel upload from stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamCancelAsync() - { - byte[] buffer = GetRandomBuffer(1 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - using (ManualResetEvent waitHandle = new ManualResetEvent(false)) - { - OperationContext operationContext = new OperationContext(); - IAsyncAction action = blob.UploadFromStreamAsync(originalBlob, null, null, operationContext); - await Task.Delay(100); - action.Cancel(); - try - { - await action; - } - catch (Exception) - { - Assert.AreEqual(operationContext.LastResult.Exception.Message, "A task was canceled."); - Assert.AreEqual(operationContext.LastResult.HttpStatusCode, 306); - //Assert.AreEqual(operationContext.LastResult.HttpStatusMessage, "Unused"); - } - TestHelper.AssertNAttempts(operationContext, 1); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - }*/ - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobReadStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobReadStreamTest.cs deleted file mode 100644 index aafaeb9300d06..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobReadStreamTest.cs +++ /dev/null @@ -1,383 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobReadStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - using (Stream blobStream = await blob.OpenReadAsync()) - { - await TestHelper.AssertStreamsAreEqualAsync(wholeBlob, blobStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Download a blob using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(5 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - Stream readStream = await blob.OpenReadAsync(); - using (Stream blobStream = readStream) - { - TestHelper.AssertStreamsAreEqual(wholeBlob, blobStream); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadLockToETagTestAsync() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream; - await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream; - long length = blobStreamForRead.Length; - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenReadAsync(accessCondition, null, opContext), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Modify a blob while downloading it using CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadLockToETagTestAsync() - { - byte[] outBuffer = new byte[1 * 1024 * 1024]; - byte[] buffer = GetRandomBuffer(2 * outBuffer.Length); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = outBuffer.Length; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream; - await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - Stream blobStreamForRead = blobStream; - long length = blobStreamForRead.Length; - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blobStreamForRead.ReadAsync(outBuffer, 0, outBuffer.Length), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - - opContext = new OperationContext(); - AccessCondition accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1))); - await blob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenReadAsync(accessCondition, null, opContext), - opContext, - "Blob read stream should fail if blob is modified during read", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - private static async Task BlobReadStreamSeekAndCompareAsync(Stream blobStream, byte[] bufferToCompare, long offset, int readSize, int expectedReadCount) - { - byte[] testBuffer = new byte[readSize]; - - int readCount = await blobStream.ReadAsync(testBuffer, 0, readSize); - Assert.AreEqual(expectedReadCount, readCount); - - for (int i = 0; i < expectedReadCount; i++) - { - Assert.AreEqual(bufferToCompare[i + offset], testBuffer[i]); - } - - return expectedReadCount; - } - - private static async Task BlobReadStreamSeekTestAsync(Stream blobStream, long streamReadSize, byte[] bufferToCompare) - { - int attempts = 1; - long position = 0; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 512, 512); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-128, SeekOrigin.End); - position = bufferToCompare.Length - 128; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 128); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(4096, SeekOrigin.Begin); - position = 4096; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(4096, SeekOrigin.Current); - position += 4096; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-4096, SeekOrigin.Current); - position -= 4096; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 128, 128); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(streamReadSize + 4096 - 512, SeekOrigin.Begin); - position = streamReadSize + 4096 - 512; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 512); - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 1024); - attempts++; - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-1024, SeekOrigin.Current); - position -= 1024; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 2048, 2048); - Assert.AreEqual(position, blobStream.Position); - blobStream.Seek(-128, SeekOrigin.End); - position = bufferToCompare.Length - 128; - Assert.AreEqual(position, blobStream.Position); - position += await BlobReadStreamSeekAndCompareAsync(blobStream, bufferToCompare, position, 1024, 128); - Assert.AreEqual(position, blobStream.Position); - return attempts; - } - - [TestMethod] - [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobReadStreamSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - int attempts = await BlobReadStreamSeekTestAsync(blobStream, blob.StreamMinimumReadSizeInBytes, buffer); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Seek and read in a CloudBlobStream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobReadStreamSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - } - - OperationContext opContext = new OperationContext(); - using (Stream blobStream = await blob.OpenReadAsync(null, null, opContext)) - { - int attempts = await BlobReadStreamSeekTestAsync(blobStream, blob.StreamMinimumReadSizeInBytes, buffer); - TestHelper.AssertNAttempts(opContext, attempts); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobStreamTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobStreamTests.cs deleted file mode 100644 index f16821553c833..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobStreamTests.cs +++ /dev/null @@ -1,314 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobStreamTests : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("BlobSeek")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream, null, null, null); - using (Stream blobStream = await blob.OpenReadAsync()) - { - Stream blobStreamForRead = blobStream; - blobStreamForRead.Seek(2048, 0); - byte[] buff = new byte[100]; - int numRead = await blobStreamForRead.ReadAsync(buff, 0, 100); - Assert.AreEqual(numRead, 0); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenWriteTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream; - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - await blobStreamForWrite.FlushAsync(); - - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - await blob.DownloadRangeToStreamAsync(dstStream, null, null); - - MemoryStream memStream = new MemoryStream(buffer); - TestHelper.AssertStreamsAreEqual(memStream, dstStream); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenReadTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream); - - Stream dstStream = await blob.OpenReadAsync(); - using (Stream dstStreamForRead = dstStream) - { - TestHelper.AssertStreamsAreEqual(srcStream, dstStreamForRead); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("OpenReadWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenReadWriteTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream; - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - await blobStreamForWrite.FlushAsync(); - } - - using (Stream dstStream = await blob.OpenReadAsync()) - { - Stream dstStreamForRead = dstStream; - MemoryStream memoryStream = new MemoryStream(buffer); - TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("OpenWriteSeekRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobOpenWriteSeekReadTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - MemoryStream memoryStream = new MemoryStream(buffer); - using (CloudBlobStream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream; - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - - Assert.AreEqual(blobStreamForWrite.Position, 2048); - - blobStreamForWrite.Seek(1024, 0); - memoryStream.Seek(1024, 0); - Assert.AreEqual(blobStreamForWrite.Position, 1024); - - byte[] testBuffer = GetRandomBuffer(1024); - - await memoryStream.WriteAsync(testBuffer, 0, 1024); - await blobStreamForWrite.WriteAsync(testBuffer, 0, 1024); - Assert.AreEqual(blobStreamForWrite.Position, memoryStream.Position); - - await blobStreamForWrite.FlushAsync(); - } - - using (Stream dstStream = await blob.OpenReadAsync()) - { - Stream dstStreamForRead = dstStream; - TestHelper.AssertStreamsAreEqual(memoryStream, dstStreamForRead); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Read when opened in OpenWrite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobReadWhenOpenWriteAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - bool thrown = false; - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - MemoryStream memoryStream = new MemoryStream(buffer); - using (Stream blobStream = await blob.OpenWriteAsync(2048)) - { - Stream blobStreamForWrite = blobStream; - await blobStreamForWrite.WriteAsync(buffer, 0, 2048); - byte[] testBuffer = new byte[2048]; - try - { - await blobStreamForWrite.ReadAsync(testBuffer, 0, 2048); - } - catch (NotSupportedException) - { - thrown = true; - } - - Assert.IsTrue(thrown); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Write when opened in OpenRead")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobWriteWhenOpenReadAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream); - bool thrown = false; - byte[] testBuffer = new byte[2048]; - using (Stream blobStream = await blob.OpenReadAsync()) - { - Stream blobStreamForRead = blobStream; - try - { - await blobStreamForRead.WriteAsync(testBuffer, 0, 2048); - } - catch (NotSupportedException) - { - thrown = true; - } - - Assert.IsTrue(thrown); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobTestBase.cs deleted file mode 100644 index ebe8cdad8102e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobTestBase.cs +++ /dev/null @@ -1,97 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - public partial class BlobTestBase : TestBase - { - public static async Task WaitForCopyAsync(ICloudBlob blob) - { - bool copyInProgress = true; - while (copyInProgress) - { - await Task.Delay(1000); - await blob.FetchAttributesAsync(); - copyInProgress = (blob.CopyState.Status == CopyStatus.Pending); - } - } - - public static async Task> CreateBlobsAsync(CloudBlobContainer container, int count, BlobType type) - { - string name; - List blobs = new List(); - for (int i = 0; i < count; i++) - { - switch (type) - { - case BlobType.BlockBlob: - name = "bb" + Guid.NewGuid().ToString(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference(name); - await blockBlob.PutBlockListAsync(new string[] { }); - blobs.Add(name); - break; - - case BlobType.PageBlob: - name = "pb" + Guid.NewGuid().ToString(); - CloudPageBlob pageBlob = container.GetPageBlobReference(name); - await pageBlob.CreateAsync(0); - blobs.Add(name); - break; - } - } - return blobs; - } - - public static async Task UploadTextAsync(ICloudBlob blob, string text, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - byte[] textAsBytes = encoding.GetBytes(text); - using (MemoryStream stream = new MemoryStream()) - { - await stream.WriteAsync(textAsBytes, 0, textAsBytes.Length); - if (blob.BlobType == BlobType.PageBlob) - { - int lastPageSize = (int)(stream.Length % 512); - if (lastPageSize != 0) - { - byte[] padding = new byte[512 - lastPageSize]; - await stream.WriteAsync(padding, 0, padding.Length); - } - } - - stream.Seek(0, SeekOrigin.Begin); - blob.ServiceClient.ParallelOperationThreadCount = 2; - await blob.UploadFromStreamAsync(stream, accessCondition, options, operationContext); - } - } - - public static async Task DownloadTextAsync(ICloudBlob blob, Encoding encoding, AccessCondition accessCondition = null, BlobRequestOptions options = null, OperationContext operationContext = null) - { - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream, accessCondition, options, operationContext); - byte[] buffer = stream.ToArray(); - return encoding.GetString(buffer, 0, buffer.Length); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobUploadDownloadTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobUploadDownloadTest.cs deleted file mode 100644 index 44aed4cfc2dd4..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobUploadDownloadTest.cs +++ /dev/null @@ -1,562 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobUploadDownloadTest : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public async Task TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - await this.testContainer.CreateIfNotExistsAsync(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public async Task TestCleanup() - { - await this.testContainer.DeleteIfExistsAsync(); - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Download a specific range of the blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobDownloadToStreamRangeTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(wholeBlob); - - byte[] testBuffer = new byte[1024]; - MemoryStream blobStream = new MemoryStream(testBuffer); - Exception ex = await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadRangeToStreamAsync(blobStream, 0, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - await blob.DownloadRangeToStreamAsync(blobStream, 0, 1024); - Assert.AreEqual(blobStream.Position, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream, wholeBlob, 0, 0, 1024); - - CloudPageBlob blob2 = this.testContainer.GetPageBlobReference("blob1"); - MemoryStream blobStream2 = new MemoryStream(testBuffer); - ex = await TestHelper.ExpectedExceptionAsync( - async () => await blob2.DownloadRangeToStreamAsync(blobStream, 1024, 0), - "Requesting 0 bytes when downloading range should not work"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - await blob2.DownloadRangeToStreamAsync(blobStream2, 1024, 1024); - TestHelper.AssertStreamsAreEqualAtIndex(blobStream2, wholeBlob, 0, 1024, 1024); - - AssertAreEqual(blob, blob2); - } - } - - [TestMethod] - [Description("Upload a stream to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobUploadFromStreamTestAsync() - { - byte[] buffer = GetRandomBuffer(2 * 1024); - - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - using (MemoryStream srcStream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(srcStream); - byte[] testBuffer = new byte[2048]; - MemoryStream dstStream = new MemoryStream(testBuffer); - await blob.DownloadRangeToStreamAsync(dstStream, null, null); - TestHelper.AssertStreamsAreEqual(srcStream, dstStream); - } - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadDownloadFileAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoUploadDownloadFileAsync(blob, 0); - await this.DoUploadDownloadFileAsync(blob, 4096); - await this.DoUploadDownloadFileAsync(blob, 4097); - } - - [TestMethod] - [Description("Upload from file to a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadDownloadFileAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoUploadDownloadFileAsync(blob, 0); - await this.DoUploadDownloadFileAsync(blob, 4096); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.DoUploadDownloadFileAsync(blob, 4097), - "Page blobs must be 512-byte aligned"); - } - - private async Task DoUploadDownloadFileAsync(ICloudBlob blob, int fileSize) - { - string inputFileName = Path.GetTempFileName(); - string outputFileName = Path.GetTempFileName(); - - try - { - byte[] buffer = GetRandomBuffer(fileSize); - using (FileStream file = new FileStream(inputFileName, FileMode.Create, FileAccess.Write)) - { - await file.WriteAsync(buffer, 0, buffer.Length); - } - - await blob.UploadFromFileAsync(inputFileName, FileMode.Open); - - OperationContext context = new OperationContext(); - await blob.UploadFromFileAsync(inputFileName, FileMode.Open, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadToFileAsync(outputFileName, FileMode.CreateNew), - "CreateNew on an existing file should fail"); - - context = new OperationContext(); - await blob.DownloadToFileAsync(outputFileName, FileMode.Create, null, null, context); - Assert.IsNotNull(context.LastResult.ServiceRequestID); - - using ( - FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - await TestHelper.AssertStreamsAreEqualAsync(inputFileStream, outputFileStream); - } - - await blob.DownloadToFileAsync(outputFileName, FileMode.Append); - - using ( - FileStream inputFileStream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read), - outputFileStream = new FileStream(outputFileName, FileMode.Open, FileAccess.Read)) - { - Assert.AreEqual(2 * fileSize, outputFileStream.Length); - - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - - inputFileStream.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < fileSize; i++) - { - Assert.AreEqual(inputFileStream.ReadByte(), outputFileStream.ReadByte()); - } - } - } - finally - { - File.Delete(inputFileName); - File.Delete(outputFileName); - } - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 4 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 1 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 2 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 512, 0, 511); - } - - [TestMethod] - [Description("Upload a blob using a byte array")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 4 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 0, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 1 * 512, 2 * 512); - await this.DoUploadFromByteArrayTestAsync(blob, 4 * 512, 2 * 512, 2 * 512); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.DoUploadFromByteArrayTestAsync(blob, 512, 0, 511), - "Page blobs must be 512-byte aligned"); - } - - private async Task DoUploadFromByteArrayTestAsync(ICloudBlob blob, int bufferSize, int bufferOffset, int count) - { - byte[] buffer = GetRandomBuffer(bufferSize); - byte[] downloadedBuffer = new byte[bufferSize]; - int downloadLength; - - await blob.UploadFromByteArrayAsync(buffer, bufferOffset, count); - downloadLength = await blob.DownloadToByteArrayAsync(downloadedBuffer, 0); - - Assert.AreEqual(count, downloadLength); - - for (int i = 0; i < count; i++) - { - Assert.AreEqual(buffer[i + bufferOffset], downloadedBuffer[i]); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadToByteArrayAsyncOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, true); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadToByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, false); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadToByteArrayAsyncOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 0, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 1 * 512, 2 * 512, 1 * 512, true); - await this.DoDownloadToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, true); - } - - private async Task DoDownloadToByteArrayAsyncTest(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, bool isOverload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (!isOverload) - { - await blob.UploadFromStreamAsync(originalBlob); - downloadLength = await blob.DownloadToByteArrayAsync(resultBuffer, bufferOffset); - } - else - { - await blob.UploadFromStreamAsync(originalBlob); - OperationContext context = new OperationContext(); - downloadLength = await blob.DownloadToByteArrayAsync(resultBuffer, bufferOffset, null, null, context); - } - - int downloadSize = Math.Min(blobSize, bufferSize - bufferOffset); - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < blob.Properties.Length; i++) - { - Assert.AreEqual(buffer[i], resultBuffer[bufferOffset + i]); - } - - for (int j = 0; j < bufferOffset; j++) - { - Assert.AreEqual(0, resultBuffer2[j]); - } - - if (bufferOffset + blobSize < bufferSize) - { - for (int k = bufferOffset + blobSize; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer2[k]); - } - } - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayAsyncOverload() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, true); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, false); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, false); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, false); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayAsyncOverload() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 0, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, null, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 1 * 512, null, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 1 * 512, 0, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 1 * 512, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 2 * 512, 4 * 512, 2 * 512, 1 * 512, 2 * 512, true); - - // Edge cases - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 1023, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 0, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 0, 512, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 1023, 1, true); - await this.DoDownloadRangeToByteArrayAsyncTest(blob, 1024, 1024, 512, 0, 512, true); - } - - /// - /// Single put blob and get blob. - /// - /// The blob size. - /// The output buffer size. - /// The output buffer offset. - /// The blob offset. - /// Length of the data range to download. - /// True when the overloaded method for DownloadRangeToByteArrayAsync is called. False when the basic method is called. - private async Task DoDownloadRangeToByteArrayAsyncTest(ICloudBlob blob, int blobSize, int bufferSize, int bufferOffset, long? blobOffset, long? length, bool isOverload) - { - int downloadLength; - byte[] buffer = GetRandomBuffer(blobSize); - byte[] resultBuffer = new byte[bufferSize]; - byte[] resultBuffer2 = new byte[bufferSize]; - - using (MemoryStream originalBlob = new MemoryStream(buffer)) - { - if (!isOverload) - { - await blob.UploadFromStreamAsync(originalBlob); - downloadLength = await blob.DownloadRangeToByteArrayAsync(resultBuffer, bufferOffset, blobOffset, length); - } - else - { - await blob.UploadFromStreamAsync(originalBlob); - OperationContext context = new OperationContext(); - downloadLength = await blob.DownloadRangeToByteArrayAsync(resultBuffer, bufferOffset, blobOffset, length, null, null, context); - } - - int downloadSize = Math.Min(blobSize - (int)(blobOffset.HasValue ? blobOffset.Value : 0), bufferSize - bufferOffset); - if (length.HasValue && (length.Value < downloadSize)) - { - downloadSize = (int)length.Value; - } - - Assert.AreEqual(downloadSize, downloadLength); - - for (int i = 0; i < bufferOffset; i++) - { - Assert.AreEqual(0, resultBuffer[i]); - } - - for (int j = 0; j < downloadLength; j++) - { - Assert.AreEqual(buffer[(blobOffset.HasValue ? blobOffset.Value : 0) + j], resultBuffer[bufferOffset + j]); - } - - for (int k = bufferOffset + downloadLength; k < bufferSize; k++) - { - Assert.AreEqual(0, resultBuffer[k]); - } - } - } - - #region Negative tests - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadRangeToByteArrayNegativeTestsAsync() - { - CloudBlockBlob blob = this.testContainer.GetBlockBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayNegativeTestsAsync(blob); - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDownloadRangeToByteArrayNegativeTestsAsync() - { - CloudPageBlob blob = this.testContainer.GetPageBlobReference("blob1"); - await this.DoDownloadRangeToByteArrayNegativeTestsAsync(blob); - } - - private async Task DoDownloadRangeToByteArrayNegativeTestsAsync(ICloudBlob blob) - { - int blobLength = 1024; - int resultBufSize = 1024; - byte[] buffer = GetRandomBuffer(blobLength); - byte[] resultBuffer = new byte[resultBufSize]; - - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.UploadFromStreamAsync(stream); - - OperationContext context = new OperationContext(); - await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, 1024, 1, null, null, context), context, "Try invalid length", HttpStatusCode.RequestedRangeNotSatisfiable); - StorageException ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadToByteArrayAsync(resultBuffer, 1024), "Provide invalid offset"); - Assert.IsInstanceOfType(ex.InnerException, typeof(NotSupportedException)); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 1023, 0, 2), "Should fail when offset + length required is greater than size of the buffer"); - Assert.IsInstanceOfType(ex.InnerException, typeof(NotSupportedException)); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, 0, -10), "Fail when a negative length is specified"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, -10, 0, 20), "Fail if a negative offset is provided"); - ex = await TestHelper.ExpectedExceptionAsync(async () => await blob.DownloadRangeToByteArrayAsync(resultBuffer, 0, -10, 20), "Fail if a negative blob offset is provided"); - Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentOutOfRangeException)); - } - } - #endregion - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobWriteStreamTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobWriteStreamTest.cs deleted file mode 100644 index aa5033afeef44..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/BlobWriteStreamTest.cs +++ /dev/null @@ -1,680 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class BlobWriteStreamTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create blobs using blob stream")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobWriteStreamOpenAndCloseAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - using (Stream writeStream = await blockBlob.OpenWriteAsync()) - { - } - - CloudBlockBlob blockBlob2 = container.GetBlockBlobReference("blob1"); - await blockBlob2.FetchAttributesAsync(); - Assert.AreEqual(0, blockBlob2.Properties.Length); - Assert.AreEqual(BlobType.BlockBlob, blockBlob2.Properties.BlobType); - - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await pageBlob.OpenWriteAsync(null, null, null, opContext), - opContext, - "Opening a page blob stream with no size should fail on a blob that does not exist", - HttpStatusCode.NotFound); - using (Stream writeStream = await pageBlob.OpenWriteAsync(1024)) - { - } - using (Stream writeStream = await pageBlob.OpenWriteAsync(null)) - { - } - - CloudPageBlob pageBlob2 = container.GetPageBlobReference("blob2"); - await pageBlob2.FetchAttributesAsync(); - Assert.AreEqual(1024, pageBlob2.Properties.Length); - Assert.AreEqual(BlobType.PageBlob, pageBlob2.Properties.BlobType); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamOpenWithAccessConditionAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - OperationContext context = new OperationContext(); - - CloudBlockBlob existingBlob = container.GetBlockBlobReference("blob"); - await existingBlob.PutBlockListAsync(new List()); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotFound); - - blob = container.GetBlockBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetBlockBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.NotModified); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await existingBlob.SetPropertiesAsync(); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetBlockBlobReference("blob7"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(accessCondition, null, context); - await blob.PutBlockListAsync(new List()); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - blob = container.GetBlockBlobReference("blob8"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value); - blobStream = await existingBlob.OpenWriteAsync(accessCondition, null, context); - await existingBlob.SetPropertiesAsync(); - await TestHelper.ExpectedExceptionAsync( - () => - { - blobStream.Dispose(); - return Task.FromResult(true); - }, - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a blob using blob stream by specifying an access condition")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamOpenWithAccessConditionAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - OperationContext context = new OperationContext(); - - CloudPageBlob existingBlob = container.GetPageBlobReference("blob"); - await existingBlob.CreateAsync(1024); - - CloudPageBlob blob = container.GetPageBlobReference("blob2"); - AccessCondition accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - blob = container.GetPageBlobReference("blob3"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - Stream blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob4"); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob5"); - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - blob = container.GetPageBlobReference("blob6"); - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await blob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(existingBlob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(existingBlob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "BlobWriteStream.Dispose with a non-met condition should fail", - HttpStatusCode.Conflict); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(1)); - blobStream = await existingBlob.OpenWriteAsync(1024, accessCondition, null, context); - blobStream.Dispose(); - - accessCondition = AccessCondition.GenerateIfNotModifiedSinceCondition(existingBlob.Properties.LastModified.Value.AddMinutes(-1)); - await TestHelper.ExpectedExceptionAsync( - async () => await existingBlob.OpenWriteAsync(1024, accessCondition, null, context), - context, - "OpenWriteAsync with a non-met condition should fail", - HttpStatusCode.PreconditionFailed); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.ParallelOperationThreadCount = 2; - string name = GetRandomContainerName(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - using (Stream writeStream = await blob.OpenWriteAsync()) - { - Stream blobStream = writeStream; - - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - await blobStream.FlushAsync(); - } - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload a block blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamSeekTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - using (Stream writeStream = await blob.OpenWriteAsync()) - { - Stream blobStream = writeStream; - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Block blob write stream should not be seekable"); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobWriteStreamFlushTestAsync() - { - byte[] buffer = GetRandomBuffer(512 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = await blob.OpenWriteAsync(null, null, opContext)) - { - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - } - - Assert.AreEqual(1, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await Task.Factory.FromAsync(blobStream.BeginCommit, blobStream.EndCommit, null); - - Assert.AreEqual(4, opContext.RequestResults.Count); - } - - Assert.AreEqual(4, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamBasicTestAsync() - { - byte[] buffer = GetRandomBuffer(6 * 512); - - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 8 * 512; - - using (MemoryStream wholeBlob = new MemoryStream()) - { - using (Stream writeStream = await blob.OpenWriteAsync(buffer.Length * 3)) - { - Stream blobStream = writeStream; - - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - await blobStream.FlushAsync(); - } - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - - using (Stream writeStream = await blob.OpenWriteAsync(null)) - { - Stream blobStream = writeStream; - blobStream.Seek(buffer.Length / 2, SeekOrigin.Begin); - wholeBlob.Seek(buffer.Length / 2, SeekOrigin.Begin); - - for (int i = 0; i < 2; i++) - { - blobStream.Write(buffer, 0, buffer.Length); - wholeBlob.Write(buffer, 0, buffer.Length); - Assert.AreEqual(wholeBlob.Position, blobStream.Position); - } - - await blobStream.FlushAsync(); - } - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload a page blob using blob stream and verify contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamRandomSeekTestAsync() - { - byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 2; - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - using (MemoryStream wholeBlob = new MemoryStream()) - { - using (Stream writeStream = await blob.OpenWriteAsync(buffer.Length)) - { - Stream blobStream = writeStream; - TestHelper.ExpectedException( - () => blobStream.Seek(1, SeekOrigin.Begin), - "Page blob stream should not allow unaligned seeks"); - - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - Random random = new Random(); - for (int i = 0; i < 10; i++) - { - int offset = random.Next(buffer.Length / 512) * 512; - SeekRandomly(blobStream, offset); - await blobStream.WriteAsync(buffer, 0, buffer.Length - offset); - wholeBlob.Seek(offset, SeekOrigin.Begin); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length - offset); - } - } - - await blob.FetchAttributesAsync(); - Assert.IsNull(blob.Properties.ContentMD5); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test the effects of blob stream's flush functionality")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobWriteStreamFlushTestAsync() - { - byte[] buffer = GetRandomBuffer(512); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 1024; - using (MemoryStream wholeBlob = new MemoryStream()) - { - OperationContext opContext = new OperationContext(); - using (CloudBlobStream blobStream = await blob.OpenWriteAsync(4 * 512, null, null, opContext)) - { - for (int i = 0; i < 3; i++) - { - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - } - - Assert.AreEqual(2, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await blobStream.FlushAsync(); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await blobStream.WriteAsync(buffer, 0, buffer.Length); - await wholeBlob.WriteAsync(buffer, 0, buffer.Length); - - Assert.AreEqual(3, opContext.RequestResults.Count); - - await Task.Factory.FromAsync(blobStream.BeginCommit, blobStream.EndCommit, null); - - Assert.AreEqual(4, opContext.RequestResults.Count); - } - - Assert.AreEqual(4, opContext.RequestResults.Count); - - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobClientTest.cs deleted file mode 100644 index 5b23b58c3e0d3..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobClientTest.cs +++ /dev/null @@ -1,463 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobClientTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a service client with URI and credentials")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientConstructor() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - Assert.IsTrue(blobClient.BaseUri.ToString().Contains(TestBase.TargetTenantConfig.BlobServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, blobClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, blobClient.AuthenticationScheme); - } - - [TestMethod] - [Description("Create a service client with uppercase account name")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientWithUppercaseAccountNameAsync() - { - StorageCredentials credentials = new StorageCredentials(TestBase.StorageCredentials.AccountName.ToUpper(), Convert.ToBase64String(TestBase.StorageCredentials.ExportKey())); - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.BlobServiceEndpoint); - CloudBlobClient blobClient = new CloudBlobClient(baseAddressUri, TestBase.StorageCredentials); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - await container.ExistsAsync(); - } - - [TestMethod] - [Description("Compare service client properties of blob objects")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobClientObjects() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference("container"); - Assert.AreEqual(blobClient, container.ServiceClient); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blockblob"); - Assert.AreEqual(blobClient, blockBlob.ServiceClient); - CloudPageBlob pageBlob = container.GetPageBlobReference("pageblob"); - Assert.AreEqual(blobClient, pageBlob.ServiceClient); - - CloudBlobContainer container2 = GetRandomContainerReference(); - Assert.AreNotEqual(blobClient, container2.ServiceClient); - CloudBlockBlob blockBlob2 = container2.GetBlockBlobReference("blockblob"); - Assert.AreEqual(container2.ServiceClient, blockBlob2.ServiceClient); - CloudPageBlob pageBlob2 = container2.GetPageBlobReference("pageblob"); - Assert.AreEqual(container2.ServiceClient, pageBlob2.ServiceClient); - } - - [TestMethod] - [Description("List blobs with prefix")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListBlobsSegmentedWithPrefixAsync() - { - string name = "bb" + GetRandomContainerName(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer rootContainer = blobClient.GetRootContainerReference(); - CloudBlobContainer container = blobClient.GetContainerReference(name); - - try - { - await rootContainer.CreateIfNotExistsAsync(); - await container.CreateAsync(); - - List blobNames = await CreateBlobsAsync(container, 3, BlobType.BlockBlob); - List rootBlobNames = await CreateBlobsAsync(rootContainer, 2, BlobType.BlockBlob); - - BlobResultSegment results; - BlobContinuationToken token = null; - do - { - results = await blobClient.ListBlobsSegmentedAsync("bb", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - await blob.DeleteAsync(); - rootBlobNames.Remove(blob.Name); - } - } - while (token != null); - Assert.AreEqual(0, rootBlobNames.Count); - - results = await blobClient.ListBlobsSegmentedAsync("bb", token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - results = await blobClient.ListBlobsSegmentedAsync(name, token); - Assert.AreEqual(0, results.Results.Count()); - Assert.IsNull(results.ContinuationToken); - - token = null; - do - { - results = await blobClient.ListBlobsSegmentedAsync(name + "/", token); - token = results.ContinuationToken; - - foreach (CloudBlockBlob blob in results.Results) - { - Assert.IsTrue(blobNames.Remove(blob.Name)); - } - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("List containers")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListContainersSegmentedAsync() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - await blobClient.GetContainerReference(containerName).CreateAsync(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = await blobClient.ListContainersSegmentedAsync(token); - token = resultSegment.ContinuationToken; - - foreach (CloudBlobContainer container in resultSegment.Results) - { - listedContainerNames.Add(container.Name); - } - } - while (token != null); - - foreach (string containerName in listedContainerNames) - { - if (containerNames.Remove(containerName)) - { - await blobClient.GetContainerReference(containerName).DeleteAsync(); - } - } - - Assert.AreEqual(0, containerNames.Count); - } - - [TestMethod] - [Description("List containers with prefix using segmented listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientListContainersSegmentedWithPrefixAsync() - { - string name = GetRandomContainerName(); - List containerNames = new List(); - CloudBlobClient blobClient = GenerateCloudBlobClient(); - - for (int i = 0; i < 3; i++) - { - string containerName = name + i.ToString(); - containerNames.Add(containerName); - await blobClient.GetContainerReference(containerName).CreateAsync(); - } - - List listedContainerNames = new List(); - BlobContinuationToken token = null; - do - { - ContainerResultSegment resultSegment = await blobClient.ListContainersSegmentedAsync(name, ContainerListingDetails.None, 1, token, null, null); - token = resultSegment.ContinuationToken; - - int count = 0; - foreach (CloudBlobContainer container in resultSegment.Results) - { - count++; - listedContainerNames.Add(container.Name); - } - Assert.IsTrue(count <= 1); - } - while (token != null); - - Assert.AreEqual(containerNames.Count, listedContainerNames.Count); - foreach (string containerName in listedContainerNames) - { - Assert.IsTrue(containerNames.Remove(containerName)); - await blobClient.GetContainerReference(containerName).DeleteAsync(); - } - } - - [TestMethod] - [Description("Test Create Container with Shared Key Lite")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientCreateContainerSharedKeyLiteAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - blobClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string containerName = GetRandomContainerName(); - CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName); - await blobContainer.CreateAsync(); - - bool exists = await blobContainer.ExistsAsync(); - Assert.IsTrue(exists); - - await blobContainer.DeleteAsync(); - } - - [TestMethod] - [Description("Upload a blob with a small maximum execution time")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientMaximumExecutionTimeoutAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(20 * 1024 * 1024); - - try - { - await container.CreateAsync(); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(5); - - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - await blockBlob.UploadFromStreamAsync(ms); - } - catch (TimeoutException ex) - { - Assert.IsInstanceOfType(ex, typeof(TimeoutException)); - } - catch (StorageException ex) - { - Assert.IsInstanceOfType(ex.InnerException, typeof(TimeoutException)); - } - } - - using (MemoryStream ms = new MemoryStream(buffer)) - { - try - { - await pageBlob.UploadFromStreamAsync(ms); - } - catch (TimeoutException ex) - { - Assert.IsInstanceOfType(ex, typeof(TimeoutException)); - } - catch (StorageException ex) - { - Assert.IsInstanceOfType(ex.InnerException, typeof(TimeoutException)); - } - } - } - - finally - { - blobClient.MaximumExecutionTime = null; - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Make sure MaxExecutionTime is not enforced when using streams")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobClientMaximumExecutionTimeoutShouldNotBeHonoredForStreamsAsync() - { - CloudBlobClient blobClient = GenerateCloudBlobClient(); - CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); - byte[] buffer = BlobTestBase.GetRandomBuffer(1024 * 1024); - - try - { - await container.CreateAsync(); - - blobClient.MaximumExecutionTime = TimeSpan.FromSeconds(30); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); - blockBlob.StreamWriteSizeInBytes = 1024 * 1024; - blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - blockBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - pageBlob.StreamMinimumReadSizeInBytes = 1024 * 1024; - - using (CloudBlobStream bos = await blockBlob.OpenWriteAsync()) - { - DateTime start = DateTime.Now; - for (int i = 0; i < 7; i++) - { - await bos.WriteAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - await bos.WriteAsync(buffer, 0, buffer.Length); - await Task.Factory.FromAsync(bos.BeginCommit, bos.EndCommit, null); - } - - using (Stream bis = (await blockBlob.OpenReadAsync())) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += await bis.ReadAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - while (true) - { - int count = await bis.ReadAsync(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - - using (CloudBlobStream bos = await pageBlob.OpenWriteAsync(8 * 1024 * 1024)) - { - DateTime start = DateTime.Now; - for (int i = 0; i < 7; i++) - { - await bos.WriteAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last write - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - await bos.WriteAsync(buffer, 0, buffer.Length); - await Task.Factory.FromAsync(bos.BeginCommit, bos.EndCommit, null); - } - - using (Stream bis = (await pageBlob.OpenReadAsync())) - { - DateTime start = DateTime.Now; - int total = 0; - while (total < 7 * 1024 * 1024) - { - total += await bis.ReadAsync(buffer, 0, buffer.Length); - } - - // Sleep to ensure we are over the Max execution time when we do the last read - int msRemaining = (int)(blobClient.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; - - if (msRemaining > 0) - { - await Task.Delay(msRemaining); - } - - while (true) - { - int count = await bis.ReadAsync(buffer, 0, buffer.Length); - total += count; - if (count == 0) - break; - } - } - } - - finally - { - blobClient.MaximumExecutionTime = null; - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobContainerTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobContainerTest.cs deleted file mode 100644 index 16905f2a7f60b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobContainerTest.cs +++ /dev/null @@ -1,634 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlobContainerTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - private static async Task TestAccessAsync(BlobContainerPublicAccessType accessType, CloudBlobContainer container, ICloudBlob inputBlob) - { - StorageCredentials credentials = new StorageCredentials(); - container = new CloudBlobContainer(container.Uri, credentials); - CloudPageBlob blob = new CloudPageBlob(inputBlob.Uri, credentials); - OperationContext context = new OperationContext(); - BlobRequestOptions options = new BlobRequestOptions(); - - if (accessType.Equals(BlobContainerPublicAccessType.Container)) - { - await blob.FetchAttributesAsync(); - await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context); - await container.FetchAttributesAsync(); - } - else if (accessType.Equals(BlobContainerPublicAccessType.Blob)) - { - await blob.FetchAttributesAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context), - context, - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.FetchAttributesAsync(null, options, context), - context, - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.FetchAttributesAsync(null, options, context), - context, - "Fetch blob attributes while public access does not allow", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, options, context), - context, - "List blobs while public access does not allow for listing", - HttpStatusCode.NotFound); - await TestHelper.ExpectedExceptionAsync( - async () => await container.FetchAttributesAsync(null, options, context), - context, - "Fetch container attributes while public access does not allow", - HttpStatusCode.NotFound); - } - } - - [TestMethod] - [Description("Validate container references")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobContainerReference() - { - CloudBlobClient client = GenerateCloudBlobClient(); - CloudBlobContainer container = client.GetContainerReference("container"); - CloudBlockBlob blockBlob = container.GetBlockBlobReference("directory1/blob1"); - CloudPageBlob pageBlob = container.GetPageBlobReference("directory2/blob2"); - CloudBlobDirectory directory = container.GetDirectoryReference("directory3"); - CloudBlobDirectory directory2 = directory.GetSubdirectoryReference("directory4"); - - Assert.AreEqual(container, blockBlob.Container); - Assert.AreEqual(container, pageBlob.Container); - Assert.AreEqual(container, directory.Container); - Assert.AreEqual(container, directory2.Container); - Assert.AreEqual(container, directory2.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - Assert.AreEqual(container, blockBlob.Parent.Container); - } - - [TestMethod] - [Description("Create and delete a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - OperationContext operationContext = new OperationContext(); - Assert.ThrowsException( - () => container.CreateAsync(BlobContainerPublicAccessType.Off, null, operationContext).Wait(), - "Creating already exists container should fail"); - Assert.AreEqual((int)HttpStatusCode.Conflict, operationContext.LastResult.HttpStatusCode); - await container.DeleteAsync(); - } - - [TestMethod] - [Description("Try to create a container after it is created")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateIfNotExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - Assert.IsTrue(await container.CreateIfNotExistsAsync()); - Assert.IsFalse(await container.CreateIfNotExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - Assert.IsFalse(await container.DeleteIfExistsAsync()); - await container.CreateAsync(); - Assert.IsTrue(await container.DeleteIfExistsAsync()); - Assert.IsFalse(await container.DeleteIfExistsAsync()); - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithContainerAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Container, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Container, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Container, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithBlobAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Blob, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Blob, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Blob, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a container with AccessType")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithPrivateAccessTypeAsyncOverload() - { - CloudBlobContainer container = GetRandomContainerReference(); - - try - { - await container.CreateAsync(BlobContainerPublicAccessType.Off, null, null); - CloudPageBlob blob1 = container.GetPageBlobReference("blob1"); - await blob1.CreateAsync(0); - CloudPageBlob blob2 = container.GetPageBlobReference("blob2"); - await blob2.CreateAsync(0); - - await TestAccessAsync(BlobContainerPublicAccessType.Off, container, blob1); - await TestAccessAsync(BlobContainerPublicAccessType.Off, container, blob2); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Check a container's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - - try - { - Assert.IsFalse(await container2.ExistsAsync()); - - await container.CreateAsync(); - - Assert.IsTrue(await container2.ExistsAsync()); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - - Assert.IsFalse(await container2.ExistsAsync()); - } - - [TestMethod] - [Description("Set container permissions")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSetPermissionsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - BlobContainerPermissions permissions = await container.GetPermissionsAsync(); - Assert.AreEqual(BlobContainerPublicAccessType.Off, permissions.PublicAccess); - Assert.AreEqual(0, permissions.SharedAccessPolicies.Count); - - // We do not have precision at milliseconds level. Hence, we need - // to recreate the start DateTime to be able to compare it later. - DateTime start = DateTime.UtcNow; - start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second, DateTimeKind.Utc); - DateTime expiry = start.AddMinutes(30); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - permissions.SharedAccessPolicies.Add("key1", new SharedAccessBlobPolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = SharedAccessBlobPermissions.List, - }); - await container.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - permissions = await container2.GetPermissionsAsync(); - Assert.AreEqual(BlobContainerPublicAccessType.Container, permissions.PublicAccess); - Assert.AreEqual(1, permissions.SharedAccessPolicies.Count); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.HasValue); - Assert.AreEqual(start, permissions.SharedAccessPolicies["key1"].SharedAccessStartTime.Value.UtcDateTime); - Assert.IsTrue(permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.HasValue); - Assert.AreEqual(expiry, permissions.SharedAccessPolicies["key1"].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(SharedAccessBlobPermissions.List, permissions.SharedAccessPolicies["key1"].Permissions); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("key1", "value1"); - await container.CreateAsync(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - await container2.FetchAttributesAsync(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - Assert.IsTrue(container2.Properties.LastModified.Value.AddHours(1) > DateTimeOffset.Now); - Assert.IsNotNull(container2.Properties.ETag); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); - await container2.FetchAttributesAsync(); - Assert.AreEqual(0, container2.Metadata.Count); - - container.Metadata.Add("key1", "value1"); - await container.SetMetadataAsync(); - - await container2.FetchAttributesAsync(); - Assert.AreEqual(1, container2.Metadata.Count); - Assert.AreEqual("value1", container2.Metadata["key1"]); - - ContainerResultSegment results = await container.ServiceClient.ListContainersSegmentedAsync(container.Name, ContainerListingDetails.Metadata, null, null, null, null); - CloudBlobContainer container3 = results.Results.First(); - Assert.AreEqual(1, container3.Metadata.Count); - Assert.AreEqual("value1", container3.Metadata["key1"]); - - container.Metadata.Clear(); - await container.SetMetadataAsync(); - - await container2.FetchAttributesAsync(); - Assert.AreEqual(0, container2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a container with metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerRegionalSetMetadataAsync() - { - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("sk-SK"); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - container.Metadata.Add("sequence", "value"); - container.Metadata.Add("schema", "value"); - await container.CreateAsync(); - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerListBlobsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - List blobNames = await CreateBlobsAsync(container, 3, BlobType.PageBlob); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - Assert.AreEqual(blobNames.Count, results.Results.Count()); - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("List blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerListBlobsSegmentedAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - List blobNames = await CreateBlobsAsync(container, 3, BlobType.PageBlob); - - BlobContinuationToken token = null; - do - { - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, 1, token, null, null); - int count = 0; - foreach (IListBlobItem blobItem in results.Results) - { - Assert.IsInstanceOfType(blobItem, typeof(CloudPageBlob)); - Assert.IsTrue(blobNames.Remove(((CloudPageBlob)blobItem).Name)); - count++; - } - Assert.AreEqual(1, count); - token = results.ContinuationToken; - } - while (token != null); - Assert.AreEqual(0, blobNames.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Get a blob reference without knowing its type")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerGetBlobReferenceFromServerAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - Permissions = SharedAccessBlobPermissions.Read, - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - }; - - CloudBlockBlob blockBlob = container.GetBlockBlobReference("bb"); - await blockBlob.PutBlockListAsync(new List()); - - CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); - await pageBlob.CreateAsync(0); - - ICloudBlob blob1 = await container.GetBlobReferenceFromServerAsync("bb"); - Assert.IsInstanceOfType(blob1, typeof(CloudBlockBlob)); - - CloudBlockBlob blob1Snapshot = await ((CloudBlockBlob)blob1).CreateSnapshotAsync(); - await blob1.SetPropertiesAsync(); - Uri blob1SnapshotUri = new Uri(blob1Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob1Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob1SnapshotReference = await container.ServiceClient.GetBlobReferenceFromServerAsync(blob1SnapshotUri); - AssertAreEqual(blob1Snapshot.Properties, blob1SnapshotReference.Properties); - - ICloudBlob blob2 = await container.GetBlobReferenceFromServerAsync("pb"); - Assert.IsInstanceOfType(blob2, typeof(CloudPageBlob)); - - CloudPageBlob blob2Snapshot = await ((CloudPageBlob)blob2).CreateSnapshotAsync(); - await blob2.SetPropertiesAsync(); - Uri blob2SnapshotUri = new Uri(blob2Snapshot.Uri.AbsoluteUri + "?snapshot=" + blob2Snapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); - ICloudBlob blob2SnapshotReference = await container.ServiceClient.GetBlobReferenceFromServerAsync(blob2SnapshotUri); - AssertAreEqual(blob2Snapshot.Properties, blob2SnapshotReference.Properties); - - ICloudBlob blob3 = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlob.Uri); - Assert.IsInstanceOfType(blob3, typeof(CloudBlockBlob)); - - ICloudBlob blob4 = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlob.Uri); - Assert.IsInstanceOfType(blob4, typeof(CloudPageBlob)); - - string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); - StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); - Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); - - string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); - StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); - Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); - - ICloudBlob blob5 = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSASUri); - Assert.IsInstanceOfType(blob5, typeof(CloudBlockBlob)); - - ICloudBlob blob6 = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSASUri); - Assert.IsInstanceOfType(blob6, typeof(CloudPageBlob)); - - CloudBlobClient client7 = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); - ICloudBlob blob7 = await client7.GetBlobReferenceFromServerAsync(blockBlobSASUri); - Assert.IsInstanceOfType(blob7, typeof(CloudBlockBlob)); - - CloudBlobClient client8 = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); - ICloudBlob blob8 = await client8.GetBlobReferenceFromServerAsync(pageBlobSASUri); - Assert.IsInstanceOfType(blob8, typeof(CloudPageBlob)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test conditional access on a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - await container.FetchAttributesAsync(); - - string currentETag = container.Properties.ETag; - DateTimeOffset currentModifiedTime = container.Properties.LastModified.Value; - - // ETag conditional tests - container.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await container.SetMetadataAsync(); - - await container.FetchAttributesAsync(); - string newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - // LastModifiedTime tests - currentModifiedTime = container.Properties.LastModified.Value; - - container.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - container.Metadata["DateConditionalName"] = "DateConditionalValue2"; - currentETag = container.Properties.ETag; - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - await container.FetchAttributesAsync(); - newETag = container.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobDirectoryTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobDirectoryTest.cs deleted file mode 100644 index e1a625ab676fe..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlobDirectoryTest.cs +++ /dev/null @@ -1,491 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Threading.Tasks; - - [TestClass] - public class CloudBlobDirectoryTest : BlobTestBase - { - string[] Delimiters = new string[] { "$", "@", "-", "%", "/", "|"}; - - private async Task CloudBlobDirectorySetupWithDelimiterAsync(CloudBlobContainer container, string delimiter = "/") - { - try - { - for (int i = 1; i < 3; i++) - { - for (int j = 1; j < 3; j++) - { - for (int k = 1; k < 3; k++) - { - String directory = "TopDir" + i + delimiter + "MidDir" + j + delimiter + "EndDir" + k + delimiter + "EndBlob" + k; - CloudPageBlob blob1 = container.GetPageBlobReference(directory); - await blob1.CreateAsync(0); - } - } - - CloudPageBlob blob2 = container.GetPageBlobReference("TopDir" + i + delimiter + "Blob" + i); - await blob2.CreateAsync(0); - } - - return true; - } - catch (Exception e) - { - throw e; - } - - } - - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("CloudBlobDirectory Get parent")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryGetParentAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.ExistsAsync()); - Assert.AreEqual("Dir1" + delimiter + "Blob1", blob.Name); - CloudBlobDirectory parent = blob.Parent; - Assert.AreEqual(parent.Prefix, "Dir1" + delimiter); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - } - - [TestMethod] - [Description("CloudBlobDirectory flat-listing and non flat-listing")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryFlatListingAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - await container.CreateAsync(); - if (await CloudBlobDirectorySetupWithDelimiterAsync(container, delimiter)) - { - BlobResultSegment segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.None, null, null, null, null); - List simpleList1 = new List(); - simpleList1.AddRange(segment.Results); - while (segment.ContinuationToken != null) - { - segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.None, null, segment.ContinuationToken, null, null); - simpleList1.AddRange(segment.Results); - } - - Assert.IsTrue(simpleList1.Count == 3); - IListBlobItem item11 = simpleList1.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList1.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList1.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - CloudBlobDirectory midDir2 = (CloudBlobDirectory)item13; - - BlobResultSegment segment2 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1", true, BlobListingDetails.None, null, null, null, null); - List simpleList2 = new List(); - simpleList2.AddRange(segment2.Results); - while (segment2.ContinuationToken != null) - { - segment2 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1", true, BlobListingDetails.None, null, segment2.ContinuationToken, null, null); - simpleList2.AddRange(segment2.Results); - } - - Assert.IsTrue(simpleList2.Count == 2); - - IListBlobItem item21 = simpleList2.ElementAt(0); - Assert.IsTrue(item21.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item22 = simpleList2.ElementAt(1); - Assert.IsTrue(item22.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - - BlobResultSegment segment3 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1"+delimiter, false, BlobListingDetails.None, null, null, null, null); - List simpleList3 = new List(); - simpleList3.AddRange(segment3.Results); - while (segment3.ContinuationToken != null) - { - segment3 = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter + "MidDir1" + delimiter, false, BlobListingDetails.None, null, segment3.ContinuationToken, null, null); - simpleList3.AddRange(segment3.Results); - } - Assert.IsTrue(simpleList3.Count == 2); - - IListBlobItem item31 = simpleList3.ElementAt(0); - Assert.IsTrue(item31.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter)); - - IListBlobItem item32 = simpleList3.ElementAt(1); - Assert.IsTrue(item32.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir2" + delimiter)); - - BlobResultSegment segment4 = await midDir2.ListBlobsSegmentedAsync(true, BlobListingDetails.None, null, null, null, null); - List simpleList4 = new List(); - simpleList4.AddRange(segment4.Results); - while (segment4.ContinuationToken != null) - { - segment4 = await midDir2.ListBlobsSegmentedAsync(true, BlobListingDetails.None, null, segment4.ContinuationToken, null, null); - simpleList4.AddRange(segment4.Results); - } - - Assert.IsTrue(simpleList4.Count == 2); - - IListBlobItem item41 = simpleList4.ElementAt(0); - Assert.IsTrue(item41.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir1" + delimiter + "EndBlob1")); - - IListBlobItem item42 = simpleList4.ElementAt(1); - Assert.IsTrue(item42.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter + "EndDir2" + delimiter + "EndBlob2")); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Get subdirectory and then traverse back to parent")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetSubdirectoryAndTraverseBackToParentAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Get parent on root")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryGetParentOnRootAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - CloudBlobDirectory root = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory parent = root.Parent; - Assert.IsNull(parent); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Check multiple delimiters")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryMultipleDelimitersAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - ////Set the default delimiter to \ - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - await container.CreateAsync(); - try - { - if (await CloudBlobDirectorySetupWithDelimiterAsync(container, delimiter)) - { - BlobResultSegment segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.UncommittedBlobs, null, null, null, null); - List simpleList = new List(); - simpleList.AddRange(segment.Results); - while (segment.ContinuationToken != null) - { - segment = await container.ListBlobsSegmentedAsync("TopDir1" + delimiter, false, BlobListingDetails.UncommittedBlobs, null, segment.ContinuationToken, null, null); - simpleList.AddRange(segment.Results); - } - - Assert.IsTrue(simpleList.Count == 3); - - IListBlobItem item11 = simpleList.ElementAt(0); - Assert.IsTrue(item11.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "Blob1")); - - IListBlobItem item12 = simpleList.ElementAt(1); - Assert.IsTrue(item12.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter)); - - IListBlobItem item13 = simpleList.ElementAt(2); - Assert.IsTrue(item13.Uri.Equals(container.Uri + "/TopDir1" + delimiter + "MidDir2" + delimiter)); - - CloudBlobDirectory directory = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subDirectory = directory.GetSubdirectoryReference("MidDir1" + delimiter); - CloudBlobDirectory parent = subDirectory.Parent; - Assert.AreEqual(parent.Prefix, directory.Prefix); - Assert.AreEqual(parent.Uri, directory.Uri); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Hierarchical traversal")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryHierarchicalTraversalAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - ////Traverse hierarchically starting with length 1 - CloudBlobDirectory directory1 = container.GetDirectoryReference("Dir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("Dir2"); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("Dir3"); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - - CloudBlobDirectory subdir3 = subdir2.GetSubdirectoryReference("Dir4"); - CloudBlobDirectory parent3 = subdir3.Parent; - Assert.AreEqual(parent3.Prefix, subdir2.Prefix); - - CloudBlobDirectory subdir4 = subdir3.GetSubdirectoryReference("Dir5"); - CloudBlobDirectory parent4 = subdir4.Parent; - Assert.AreEqual(parent4.Prefix, subdir3.Prefix); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Get directory parent for blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryBlobParentValidateAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - try - { - CloudPageBlob blob = container.GetPageBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - [TestMethod] - [Description("Validate CloudBlobDirectory in root container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobDirectoryValidateInRootContainerAsync() - { - foreach (String delimiter in Delimiters) - { - - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - CloudBlobContainer container = client.GetContainerReference("$root"); - - CloudPageBlob pageBlob = container.GetPageBlobReference("Dir1" + delimiter + "Blob1"); - OperationContext context = new OperationContext(); - if (delimiter == "/") - { - await TestHelper.ExpectedExceptionAsync( - async () => await pageBlob.CreateAsync(0, null, null, context), context, - "Try to create a CloudBlobDirectory/blob which has a slash in its name in the root container", - HttpStatusCode.BadRequest); - } - else - { - CloudPageBlob blob = container.GetPageBlobReference("TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter + "EndBlob1"); - CloudBlobDirectory directory = blob.Parent; - Assert.AreEqual(directory.Prefix, "TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - Assert.AreEqual(directory.Uri, container.Uri + "/TopDir1" + delimiter + "MidDir1" + delimiter + "EndDir1" + delimiter); - - CloudBlobDirectory directory1 = container.GetDirectoryReference("TopDir1" + delimiter); - CloudBlobDirectory subdir1 = directory1.GetSubdirectoryReference("MidDir" + delimiter); - CloudBlobDirectory parent1 = subdir1.Parent; - Assert.AreEqual(parent1.Prefix, directory1.Prefix); - Assert.AreEqual(parent1.Uri, directory1.Uri); - - CloudBlobDirectory subdir2 = subdir1.GetSubdirectoryReference("EndDir" + delimiter); - CloudBlobDirectory parent2 = subdir2.Parent; - Assert.AreEqual(parent2.Prefix, subdir1.Prefix); - Assert.AreEqual(parent2.Uri, subdir1.Uri); - } - } - } - - [TestMethod] - [Description("Multiple delimiters in a row or empty directory names")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudBlobDirectoryDelimitersInARowAsync() - { - foreach (String delimiter in Delimiters) - { - CloudBlobClient client = GenerateCloudBlobClient(); - client.DefaultDelimiter = delimiter; - string name = GetRandomContainerName(); - CloudBlobContainer container = client.GetContainerReference(name); - - try - { - CloudPageBlob blob = container.GetPageBlobReference(delimiter + delimiter + delimiter + "Blob1"); - - ////Traverse from leaf to root - CloudBlobDirectory directory1 = blob.Parent; - Assert.AreEqual(directory1.Prefix, delimiter + delimiter + delimiter); - - CloudBlobDirectory directory2 = directory1.Parent; - Assert.AreEqual(directory2.Prefix, delimiter + delimiter); - - CloudBlobDirectory directory3 = directory2.Parent; - Assert.AreEqual(directory3.Prefix, delimiter); - - ////Traverse from root to leaf - CloudBlobDirectory directory4 = container.GetDirectoryReference(delimiter); - CloudBlobDirectory directory5 = directory4.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory5.Prefix, delimiter + delimiter); - - CloudBlobDirectory directory6 = directory5.GetSubdirectoryReference(delimiter); - Assert.AreEqual(directory6.Prefix, delimiter + delimiter + delimiter); - - CloudPageBlob blob2 = directory6.GetPageBlobReference("Blob1"); - Assert.AreEqual(blob2.Name, delimiter + delimiter + delimiter + "Blob1"); - Assert.AreEqual(blob2.Uri, blob.Uri); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } - - - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlockBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlockBlobTest.cs deleted file mode 100644 index 4aa7e67046b35..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudBlockBlobTest.cs +++ /dev/null @@ -1,1378 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudBlockBlobTest : BlobTestBase - { - private static async Task CreateForTestAsync(CloudBlockBlob blob, int blockCount, int blockSize, bool commit = true) - { - byte[] buffer = GetRandomBuffer(blockSize); - List blocks = GetBlockIdList(blockCount); - - foreach (string block in blocks) - { - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, stream, null); - } - } - - if (commit) - { - await blob.PutBlockListAsync(blocks); - } - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a zero-length block blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCreateAndDeleteAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 0, 0); - Assert.IsTrue(await blob.ExistsAsync()); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - await CreateForTestAsync(blob, 0, 0); - Assert.IsTrue(await blob.DeleteIfExistsAsync()); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - - Assert.IsFalse(await blob2.ExistsAsync()); - - await CreateForTestAsync(blob, 2, 1024); - - Assert.IsTrue(await blob2.ExistsAsync()); - Assert.AreEqual(2048, blob2.Properties.Length); - - await blob.DeleteAsync(); - - Assert.IsFalse(await blob2.ExistsAsync()); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobFetchAttributesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - Assert.AreEqual(-1, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob.Properties.BlobType); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.BlockBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSetPropertiesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - await Task.Delay(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - await blob.SetPropertiesAsync(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudBlockBlob blob3 = container.GetBlockBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - await blob3.DownloadToStreamAsync(stream, null, options, null); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - CloudBlockBlob blob4 = (CloudBlockBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try retrieving properties of a block blob using a page blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobFetchAttributesInvalidTypeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - Assert.ThrowsException( - () => blob2.FetchAttributesAsync(null, null, operationContext).Wait(), - "Fetching attributes of a block blob using a page blob reference should fail"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify that creating a block blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - await CreateForTestAsync(blob, 0, 0); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify that a block blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 0, 0); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - - OperationContext operationContext = new OperationContext(); - blob.Metadata["key1"] = null; - - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).Wait(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).Wait(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null); - CloudBlockBlob blob3 = (CloudBlockBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload blocks and then commit the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.FuntionalTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadAsync() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - using (MemoryStream wholeBlob = new MemoryStream()) - { - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream, null); - } - wholeBlob.Write(buffer, 0, buffer.Length); - } - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream, null); - } - } - - await blob.PutBlockListAsync(blocks); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - using (MemoryStream downloadedBlob = new MemoryStream()) - { - await blob2.DownloadToStreamAsync(downloadedBlob); - TestHelper.AssertStreamsAreEqual(wholeBlob, downloadedBlob); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload a block blob and then verify the block list")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobDownloadBlockListAsync() - { - byte[] buffer = GetRandomBuffer(1024); - List blocks = GetBlockIdList(3); - List extraBlocks = GetBlockIdList(2); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - foreach (string block in blocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream, null); - } - } - await blob.PutBlockListAsync(blocks); - - foreach (string block in extraBlocks) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(block, memoryStream, null); - } - } - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024 * blocks.Count, blob2.Properties.Length); - - IEnumerable blockList = await blob2.DownloadBlockListAsync(); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsTrue(blockItem.Committed); - Assert.IsTrue(blocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, blocks.Count); - - blockList = await blob2.DownloadBlockListAsync(BlockListingFilter.Uncommitted, null, null, null); - foreach (ListBlockItem blockItem in blockList) - { - Assert.IsFalse(blockItem.Committed); - Assert.IsTrue(extraBlocks.Remove(blockItem.Name)); - } - Assert.AreEqual(0, extraBlocks.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamWithAccessConditionAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 1, 1024); - await blob.FetchAttributesAsync(); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0), - operationContext, - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0); - - blob = container.GetBlockBlobReference("blob3"); - await CreateForTestAsync(blob, 1, 1024); - await blob.FetchAttributesAsync(); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, null, accessCondition, operationContext, true, false, 0); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamWithNonSeekableStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, true, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, false, false, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, true, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, null, null, null, true, false, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamLengthSinglePutAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload 2MB of 5MB stream - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, true, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, true, 1024); - - // Exclude last byte - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, true, true, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, false, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, false, true, 1024); - - // Upload exact amount - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, true, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, true, true, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, false, true, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, false, true, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload 2MB of 5MB stream - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, true, false, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 2 * 1024 * 1024, null, null, false, false, 1024); - - // Exclude last byte - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, true, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, true, false, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024 - 1, null, null, false, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024 - 1, null, null, false, false, 1024); - - // Upload exact amount - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, true, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, true, false, 1024); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 5 * 1024 * 1024, null, null, false, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 5 * 1024 * 1024, 4 * 1024 * 1024, null, null, false, false, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadFromStreamInvalidLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, null, true, true, 0), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, null, true, true, 1024), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 + 1, null, null, false, true, 0), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudBlockBlobUploadFromStreamAsync(container, 2 * 1024 * 1024, 2 * 1024 * 1024 - 1023, null, null, false, true, 1024), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload blob using multiple threads and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobParallelUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - container.ServiceClient.ParallelOperationThreadCount = 8; - await container.CreateAsync(); - try - { - await this.CloudBlockBlobUploadFromStreamAsync(container, 16 * 1024 * 1024, null, null, null, true, false, 0); - await this.CloudBlockBlobUploadFromStreamAsync(container, 16 * 1024 * 1024, null, null, null, true, false, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - private async Task CloudBlockBlobUploadFromStreamAsync(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, OperationContext operationContext, bool seekableSourceStream, bool allowSinglePut, int startOffset) - { - byte[] buffer = GetRandomBuffer(size); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - blob.ServiceClient.SingleBlobUploadThresholdInBytes = allowSinglePut ? buffer.Length : buffer.Length / 2; - blob.StreamWriteSizeInBytes = 1 * 1024 * 1024; - - using (MemoryStream originalBlobStream = new MemoryStream()) - { - originalBlobStream.Write(buffer, startOffset, buffer.Length - startOffset); - - Stream sourceStream; - if (seekableSourceStream) - { - MemoryStream stream = new MemoryStream(buffer); - stream.Seek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - else - { - NonSeekableMemoryStream stream = new NonSeekableMemoryStream(buffer); - stream.ForceSeek(startOffset, SeekOrigin.Begin); - sourceStream = stream; - } - - using (sourceStream) - { - if (copyLength.HasValue) - { - await blob.UploadFromStreamAsync(sourceStream, copyLength.Value, accessCondition, null, operationContext); - } - else - { - await blob.UploadFromStreamAsync(sourceStream, accessCondition, null, operationContext); - } - } - - using (MemoryStream downloadedBlobStream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlobStream); - Assert.AreEqual(copyLength ?? originalBlobStream.Length, downloadedBlobStream.Length); - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlobStream, - downloadedBlobStream, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlobStream.Length); - } - } - } - - [TestMethod] - [Description("Create snapshots of a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSnapshotAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await blob.UploadFromStreamAsync(originalData); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudBlockBlob snapshot1 = await blob.CreateSnapshotAsync(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudBlockBlob snapshot2 = await blob.CreateSnapshotAsync(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - await snapshot1.FetchAttributesAsync(); - await snapshot2.FetchAttributesAsync(); - await blob.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudBlockBlob snapshot1Clone = new CloudBlockBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - await snapshot1Clone.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudBlockBlob snapshotCopy = container.GetBlockBlobReference("blob2"); - await snapshotCopy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot1.Uri)); - await WaitForCopyAsync(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - await TestHelper.ExpectedExceptionAsync( - async () => await snapshot1.OpenWriteAsync(), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - await blob.PutBlockListAsync(new List()); - await blob.FetchAttributesAsync(); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSnapshotMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 2, 1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - await blob.SetMetadataAsync(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudBlockBlob snapshot = await blob.CreateSnapshotAsync(snapshotMetadata, null, null, null); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - await snapshot.FetchAttributesAsync(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - await CreateForTestAsync(blob, 2, 1024); - await blob.FetchAttributesAsync(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(currentETag), null, null); - - await blob.FetchAttributesAsync(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(newETag), null, operationContext), - operationContext, - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(invalidETag), null, operationContext), - operationContext, - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Put block boundaries")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobPutBlockBoundariesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - string blockId = GetBlockIdList(1).First(); - - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[0]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockId, stream, null, null, null, operationContext), - operationContext, - "Trying to upload a block with zero bytes should fail", - HttpStatusCode.BadRequest); - } - - buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockId, stream, null); - } - - buffer = new byte[4 * 1024 * 1024]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockId, stream, null); - } - - buffer = new byte[4 * 1024 * 1024 + 1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockId, stream, null, null, null, operationContext), - operationContext, - "Trying to upload a block with more than 4MB should fail", - HttpStatusCode.RequestEntityTooLarge); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload blocks and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobPutBlockAsync() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - List blockList = GetBlockIdList(2); - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - memoryStream.Seek(0, SeekOrigin.Begin); - await blob.PutBlockAsync(blockList[0], memoryStream, null); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.PutBlockAsync(blockList[1], memoryStream, null); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - await blob.PutBlockListAsync(blockList); - - using (MemoryStream blobData = new MemoryStream()) - { - await blob.DownloadToStreamAsync(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test block blob methods on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobMethodsOnPageBlobAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List blobs = await CreateBlobsAsync(container, 1, BlobType.PageBlob); - CloudBlockBlob blob = container.GetBlockBlobReference(blobs.First()); - List blockList = GetBlockIdList(1); - - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[1]; - using (MemoryStream stream = new MemoryStream(buffer)) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockAsync(blockList.First(), stream, null, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.PutBlockListAsync(blockList, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadBlockListAsync(BlockListingFilter.Committed, null, null, operationContext), - operationContext, - "Block operations should fail on page blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test block removal/addition/reordering in a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobBlockReorderingAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - List originalBlockIds = GetBlockIdList(10); - List blockIds = new List(originalBlockIds); - List blocks = new List(); - for (int i = 0; i < blockIds.Count; i++) - { - byte[] buffer = Encoding.UTF8.GetBytes(i.ToString()); - using (MemoryStream stream = new MemoryStream(buffer)) - { - await blob.PutBlockAsync(blockIds[i], stream, null); - } - blocks.Add(buffer); - } - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("0123456789", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(0); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("123456789", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(8); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("12345678", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.RemoveAt(3); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("1235678", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[9])) - { - await blob.PutBlockAsync(originalBlockIds[9], stream, null); - } - blockIds.Insert(0, originalBlockIds[9]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("91235678", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[0])) - { - await blob.PutBlockAsync(originalBlockIds[0], stream, null); - } - blockIds.Add(originalBlockIds[0]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("912356780", await DownloadTextAsync(blob, Encoding.UTF8)); - - using (MemoryStream stream = new MemoryStream(blocks[4])) - { - await blob.PutBlockAsync(originalBlockIds[4], stream, null); - } - blockIds.Insert(2, originalBlockIds[4]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("9142356780", await DownloadTextAsync(blob, Encoding.UTF8)); - - blockIds.Insert(0, originalBlockIds[0]); - await blob.PutBlockListAsync(blockIds); - Assert.AreEqual("09142356780", await DownloadTextAsync(blob, Encoding.UTF8)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadDownloadNoDataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob blob = container.GetBlockBlobReference("blob"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.UploadFromStreamAsync(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadToStreamAsync(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("List committed and uncommitted blobs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobListUncommittedBlobsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List committedBlobs = new List(); - for (int i = 0; i < 3; i++) - { - string name = "cblob" + i.ToString(); - CloudBlockBlob committedBlob = container.GetBlockBlobReference(name); - await CreateForTestAsync(committedBlob, 2, 1024); - committedBlobs.Add(name); - } - - List uncommittedBlobs = new List(); - for (int i = 0; i < 5; i++) - { - string name = "ucblob" + i.ToString(); - CloudBlockBlob uncommittedBlob = container.GetBlockBlobReference(name); - await CreateForTestAsync(uncommittedBlob, 2, 1024, false); - uncommittedBlobs.Add(name); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.UncommittedBlobs, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - foreach (ICloudBlob blob in blobs) - { - if (committedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(2 * 1024, blob.Properties.Length); - } - else if (uncommittedBlobs.Remove(blob.Name)) - { - Assert.AreEqual(0, blob.Properties.Length); - } - else - { - Assert.Fail("Blob is not found in either committed or uncommitted list"); - } - } - - Assert.AreEqual(0, committedBlobs.Count); - Assert.AreEqual(0, uncommittedBlobs.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload and download text")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobUploadTextAsync() - { - await this.DoTextUploadDownloadAsync("test", false); - await this.DoTextUploadDownloadAsync("char中文test", true); - await this.DoTextUploadDownloadAsync("", false); - } - - private async Task DoTextUploadDownloadAsync(string text, bool checkDifferentEncoding) - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateIfNotExistsAsync(); - CloudBlockBlob blob = container.GetBlockBlobReference("blob1"); - - await blob.UploadTextAsync(text); - Assert.AreEqual(text, await blob.DownloadTextAsync()); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, await blob.DownloadTextAsync(Encoding.Unicode, null, null, null)); - } - - await blob.UploadTextAsync(text, Encoding.Unicode, null, null, null); - Assert.AreEqual(text, await blob.DownloadTextAsync(Encoding.Unicode, null, null, null)); - if (checkDifferentEncoding) - { - Assert.AreNotEqual(text, await blob.DownloadTextAsync()); - } - - OperationContext context = new OperationContext(); - await blob.UploadTextAsync(text, Encoding.Unicode, null, null, context); - Assert.AreEqual(1, context.RequestResults.Count); - await blob.DownloadTextAsync(Encoding.Unicode, null, null, context); - Assert.AreEqual(2, context.RequestResults.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudPageBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudPageBlobTest.cs deleted file mode 100644 index 3c8ced33fb01e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CloudPageBlobTest.cs +++ /dev/null @@ -1,1205 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CloudPageBlobTest : BlobTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create a zero-length page blob and then delete it")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCreateAndDeleteAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.ExistsAsync()); - await blob.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Resize a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobResizeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - await blob.CreateAsync(1024); - Assert.AreEqual(1024, blob.Properties.Length); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - blob2.Properties.ContentType = "text/plain"; - await blob2.SetPropertiesAsync(); - await blob.ResizeAsync(2048); - Assert.AreEqual(2048, blob.Properties.Length); - await blob.FetchAttributesAsync(); - Assert.AreEqual("text/plain", blob.Properties.ContentType); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(2048, blob2.Properties.Length); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Use sequence number conditions on a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSequenceNumberAsync() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - - await blob.CreateAsync(buffer.Length); - Assert.IsNull(blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, 5); - Assert.AreEqual(5, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 7); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, 3); - Assert.AreEqual(7, blob.Properties.PageBlobSequenceNumber); - - await blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, null); - Assert.AreEqual(8, blob.Properties.PageBlobSequenceNumber); - - StorageException e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, null), - "SetSequenceNumber with Update should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Update, -1), - "Negative sequence numbers are not supported"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentOutOfRangeException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Max, null), - "SetSequenceNumber with Max should require a value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentNullException)); - - e = await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetSequenceNumberAsync(SequenceNumberAction.Increment, 1), - "SetSequenceNumber with Increment should require null value"); - Assert.IsInstanceOfType(e.InnerException, typeof(ArgumentException)); - - using (MemoryStream stream = new MemoryStream(buffer)) - { - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(8), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - OperationContext context = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, stream.Length, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, context), - context, - "Sequence number condition should cause Put Page to fail", - HttpStatusCode.PreconditionFailed, - "SequenceNumberConditionNotMet"); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberEqualCondition(9), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberLessThanOrEqualCondition(7), null, null); - - stream.Seek(0, SeekOrigin.Begin); - await blob.UploadFromStreamAsync(stream, AccessCondition.GenerateIfSequenceNumberLessThanCondition(8), null, null); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobDeleteIfExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - await blob.CreateAsync(0); - Assert.IsTrue(await blob.DeleteIfExistsAsync()); - Assert.IsFalse(await blob.DeleteIfExistsAsync()); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Check a blob's existence")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobExistsAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - - try - { - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - - Assert.IsFalse(await blob2.ExistsAsync()); - - await blob.CreateAsync(2048); - - Assert.IsTrue(await blob2.ExistsAsync()); - Assert.AreEqual(2048, blob2.Properties.Length); - - await blob.DeleteAsync(); - - Assert.IsFalse(await blob2.ExistsAsync()); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify the attributes of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobFetchAttributesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - Assert.AreEqual(1024, blob.Properties.Length); - Assert.IsNotNull(blob.Properties.ETag); - Assert.IsTrue(blob.Properties.LastModified > DateTimeOffset.UtcNow.AddMinutes(-5)); - Assert.IsNull(blob.Properties.CacheControl); - Assert.IsNull(blob.Properties.ContentEncoding); - Assert.IsNull(blob.Properties.ContentLanguage); - Assert.IsNull(blob.Properties.ContentType); - Assert.IsNull(blob.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unspecified, blob.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob.Properties.BlobType); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1024, blob2.Properties.Length); - Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); - Assert.IsNull(blob2.Properties.ContentEncoding); - Assert.IsNull(blob2.Properties.ContentLanguage); - Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); - Assert.IsNull(blob2.Properties.ContentMD5); - Assert.AreEqual(LeaseStatus.Unlocked, blob2.Properties.LeaseStatus); - Assert.AreEqual(BlobType.PageBlob, blob2.Properties.BlobType); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify setting the properties of a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSetPropertiesAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - string eTag = blob.Properties.ETag; - DateTimeOffset lastModified = blob.Properties.LastModified.Value; - - await Task.Delay(1000); - - blob.Properties.CacheControl = "no-transform"; - blob.Properties.ContentEncoding = "gzip"; - blob.Properties.ContentLanguage = "tr,en"; - blob.Properties.ContentMD5 = "MDAwMDAwMDA="; - blob.Properties.ContentType = "text/html"; - await blob.SetPropertiesAsync(); - Assert.IsTrue(blob.Properties.LastModified > lastModified); - Assert.AreNotEqual(eTag, blob.Properties.ETag); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual("no-transform", blob2.Properties.CacheControl); - Assert.AreEqual("gzip", blob2.Properties.ContentEncoding); - Assert.AreEqual("tr,en", blob2.Properties.ContentLanguage); - Assert.AreEqual("MDAwMDAwMDA=", blob2.Properties.ContentMD5); - Assert.AreEqual("text/html", blob2.Properties.ContentType); - - CloudPageBlob blob3 = container.GetPageBlobReference("blob1"); - using (MemoryStream stream = new MemoryStream()) - { - BlobRequestOptions options = new BlobRequestOptions() - { - DisableContentMD5Validation = true, - }; - await blob3.DownloadToStreamAsync(stream, null, options, null); - } - AssertAreEqual(blob2.Properties, blob3.Properties); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null); - CloudPageBlob blob4 = (CloudPageBlob)results.Results.First(); - AssertAreEqual(blob2.Properties, blob4.Properties); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try retrieving properties of a block blob using a page blob reference")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobFetchAttributesInvalidTypeAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - CloudBlockBlob blob2 = container.GetBlockBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - Assert.ThrowsException( - () => blob2.FetchAttributesAsync(null, null, operationContext).Wait(), - "Fetching attributes of a page blob using a block blob reference should fail"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(InvalidOperationException)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify that creating a page blob can also set its metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCreateWithMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.Metadata["key1"] = "value1"; - await blob.CreateAsync(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Verify that a page blob's metadata can be updated")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSetMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - CloudPageBlob blob2 = container.GetPageBlobReference("blob1"); - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - - OperationContext operationContext = new OperationContext(); - blob.Metadata["key1"] = null; - - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).Wait(), - "Metadata keys should have a non-null value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = ""; - Assert.ThrowsException( - () => blob.SetMetadataAsync(null, null, operationContext).Wait(), - "Metadata keys should have a non-empty value"); - Assert.IsInstanceOfType(operationContext.LastResult.Exception.InnerException, typeof(ArgumentException)); - - blob.Metadata["key1"] = "value1"; - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(1, blob2.Metadata.Count); - Assert.AreEqual("value1", blob2.Metadata["key1"]); - - BlobResultSegment results = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, null, null, null); - CloudPageBlob blob3 = (CloudPageBlob)results.Results.First(); - Assert.AreEqual(1, blob3.Metadata.Count); - Assert.AreEqual("value1", blob3.Metadata["key1"]); - - blob.Metadata.Clear(); - await blob.SetMetadataAsync(); - - await blob2.FetchAttributesAsync(); - Assert.AreEqual(0, blob2.Metadata.Count); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload/clear pages in a page blob and then verify page ranges")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobGetPageRangesAsync() - { - byte[] buffer = GetRandomBuffer(1024); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(4 * 1024); - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.WritePagesAsync(memoryStream, 512, null); - } - - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - await blob.WritePagesAsync(memoryStream, 3 * 1024, null); - } - - await blob.ClearPagesAsync(1024, 1024); - await blob.ClearPagesAsync(0, 512); - - IEnumerable pageRanges = await blob.GetPageRangesAsync(); - List expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 4 * 1024 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - pageRanges = await blob.GetPageRangesAsync(1024, 1024, null, null, null); - Assert.AreEqual(0, pageRanges.Count()); - - pageRanges = await blob.GetPageRangesAsync(512, 3 * 1024, null, null, null); - expectedPageRanges = new List() - { - new PageRange(512, 1023).ToString(), - new PageRange(3 * 1024, 7 * 512 - 1).ToString(), - }; - foreach (PageRange pageRange in pageRanges) - { - Assert.IsTrue(expectedPageRanges.Remove(pageRange.ToString())); - } - Assert.AreEqual(0, expectedPageRanges.Count); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.GetPageRangesAsync(1024, null, null, null, opContext), - opContext, - "Get Page Ranges with an offset but no count should fail", - HttpStatusCode.Unused); - Assert.IsInstanceOfType(opContext.LastResult.Exception.InnerException, typeof(ArgumentNullException)); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload pages to a page blob and then verify the contents")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobWritePagesAsync() - { - byte[] buffer = GetRandomBuffer(4 * 1024 * 1024); - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(4 * 1024 * 1024); - - using (MemoryStream memoryStream = new MemoryStream()) - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream, 0, null), - "Zero-length WritePages should fail"); - - memoryStream.SetLength(4 * 1024 * 1024 + 1); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream, 0, null), - ">4MB WritePages should fail"); - } - - using (MemoryStream resultingData = new MemoryStream()) - { - using (MemoryStream memoryStream = new MemoryStream(buffer)) - { - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(memoryStream, 512, null, null, null, opContext), - opContext, - "Writing out-of-range pages should fail", - HttpStatusCode.RequestedRangeNotSatisfiable, - "InvalidPageRange"); - - memoryStream.Seek(0, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream, 0, null); - resultingData.Write(buffer, 0, buffer.Length); - - int offset = buffer.Length - 1024; - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream, 0, null); - resultingData.Seek(0, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - - offset = buffer.Length - 2048; - memoryStream.Seek(offset, SeekOrigin.Begin); - await blob.WritePagesAsync(memoryStream, 1024, null); - resultingData.Seek(1024, SeekOrigin.Begin); - resultingData.Write(buffer, offset, buffer.Length - offset); - } - - using (MemoryStream blobData = new MemoryStream()) - { - await blob.DownloadToStreamAsync(blobData); - Assert.AreEqual(resultingData.Length, blobData.Length); - - Assert.IsTrue(blobData.ToArray().SequenceEqual(resultingData.ToArray())); - } - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamWithAccessConditionAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - AccessCondition accessCondition = AccessCondition.GenerateIfNoneMatchCondition("\"*\""); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0), - operationContext, - "Uploading a blob on top of an existing blob should fail if the ETag matches", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0); - - blob = container.GetPageBlobReference("blob3"); - await blob.CreateAsync(1024); - accessCondition = AccessCondition.GenerateIfMatchCondition(blob.Properties.ETag); - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0), - operationContext, - "Uploading a blob on top of an non-existing blob should fail when the ETag doesn't match", - HttpStatusCode.PreconditionFailed); - accessCondition = AccessCondition.GenerateIfNoneMatchCondition(blob.Properties.ETag); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, accessCondition, operationContext, 0); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, null, null, 0); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, null, null, null, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamLengthAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - // Upload half - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 0); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 1024); - - // Upload full stream - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 6 * 512, null, null, 0); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 4 * 512, null, null, 1024); - - // Exclude last page - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 5 * 512, null, null, 0); - await this.CloudPageBlobUploadFromStreamAsync(container, 6 * 512, 3 * 512, null, null, 1024); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - [TestMethod] - [Description("Single put blob and get blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadFromStreamLengthInvalidAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - await container.CreateAsync(); - try - { - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 3 * 512, 4 * 512, null, null, 0), - "The given stream does not contain the requested number of bytes from its given position."); - - await TestHelper.ExpectedExceptionAsync( - async () => await this.CloudPageBlobUploadFromStreamAsync(container, 3 * 512, 2 * 512, null, null, 1024), - "The given stream does not contain the requested number of bytes from its given position."); - } - finally - { - container.DeleteAsync().Wait(); - } - } - - private async Task CloudPageBlobUploadFromStreamAsync(CloudBlobContainer container, int size, long? copyLength, AccessCondition accessCondition, OperationContext operationContext, int startOffset) - { - byte[] buffer = GetRandomBuffer(size); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - blob.StreamWriteSizeInBytes = 512; - - using (MemoryStream originalBlobStream = new MemoryStream()) - { - originalBlobStream.Write(buffer, startOffset, buffer.Length - startOffset); - - using (MemoryStream sourceStream = new MemoryStream(buffer)) - { - sourceStream.Seek(startOffset, SeekOrigin.Begin); - if (copyLength.HasValue) - { - await blob.UploadFromStreamAsync(sourceStream, copyLength.Value, accessCondition, null, operationContext); - } - else - { - await blob.UploadFromStreamAsync(sourceStream, accessCondition, null, operationContext); - } - } - - using (MemoryStream downloadedBlobStream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(downloadedBlobStream); - Assert.AreEqual(copyLength ?? originalBlobStream.Length, downloadedBlobStream.Length); - TestHelper.AssertStreamsAreEqualAtIndex( - originalBlobStream, - downloadedBlobStream, - 0, - 0, - copyLength.HasValue ? (int)copyLength : (int)originalBlobStream.Length); - } - } - } - - [TestMethod] - [Description("Create snapshots of a page blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSnapshotAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.UploadFromStreamAsync(originalData); - Assert.IsFalse(blob.IsSnapshot); - Assert.IsNull(blob.SnapshotTime, "Root blob has SnapshotTime set"); - Assert.IsFalse(blob.SnapshotQualifiedUri.Query.Contains("snapshot")); - Assert.AreEqual(blob.Uri, blob.SnapshotQualifiedUri); - - CloudPageBlob snapshot1 = await blob.CreateSnapshotAsync(); - Assert.AreEqual(blob.Properties.ETag, snapshot1.Properties.ETag); - Assert.AreEqual(blob.Properties.LastModified, snapshot1.Properties.LastModified); - Assert.IsTrue(snapshot1.IsSnapshot); - Assert.IsNotNull(snapshot1.SnapshotTime, "Snapshot does not have SnapshotTime set"); - Assert.AreEqual(blob.Uri, snapshot1.Uri); - Assert.AreNotEqual(blob.SnapshotQualifiedUri, snapshot1.SnapshotQualifiedUri); - Assert.AreNotEqual(snapshot1.Uri, snapshot1.SnapshotQualifiedUri); - Assert.IsTrue(snapshot1.SnapshotQualifiedUri.Query.Contains("snapshot")); - - CloudPageBlob snapshot2 = await blob.CreateSnapshotAsync(); - Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); - - await snapshot1.FetchAttributesAsync(); - await snapshot2.FetchAttributesAsync(); - await blob.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, blob.Properties); - - CloudPageBlob snapshot1Clone = new CloudPageBlob(new Uri(blob.Uri + "?snapshot=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); - Assert.IsNotNull(snapshot1Clone.SnapshotTime, "Snapshot clone does not have SnapshotTime set"); - Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshot1Clone.SnapshotTime.Value); - await snapshot1Clone.FetchAttributesAsync(); - AssertAreEqual(snapshot1.Properties, snapshot1Clone.Properties); - - CloudPageBlob snapshotCopy = container.GetPageBlobReference("blob2"); - await snapshotCopy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot1.Uri)); - await WaitForCopyAsync(snapshotCopy); - Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); - - await TestHelper.ExpectedExceptionAsync( - async () => await snapshot1.OpenWriteAsync(1024), - "Trying to write to a blob snapshot should fail"); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - await blob.CreateAsync(1024); - - using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) - { - snapshotStream.Seek(0, SeekOrigin.End); - TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); - } - - BlobResultSegment resultSegment = await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.All, null, null, null, null); - List blobs = resultSegment.Results.ToList(); - Assert.AreEqual(4, blobs.Count); - AssertAreEqual(snapshot1, (ICloudBlob)blobs[0]); - AssertAreEqual(snapshot2, (ICloudBlob)blobs[1]); - AssertAreEqual(blob, (ICloudBlob)blobs[2]); - AssertAreEqual(snapshotCopy, (ICloudBlob)blobs[3]); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Create a snapshot with explicit metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSnapshotMetadataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - - blob.Metadata["Hello"] = "World"; - blob.Metadata["Marco"] = "Polo"; - await blob.SetMetadataAsync(); - - IDictionary snapshotMetadata = new Dictionary(); - snapshotMetadata["Hello"] = "Dolly"; - snapshotMetadata["Yoyo"] = "Ma"; - - CloudPageBlob snapshot = await blob.CreateSnapshotAsync(snapshotMetadata, null, null, null); - - // Test the client view against the expected metadata - // None of the original metadata should be present - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - - // Test the server view against the expected metadata - await snapshot.FetchAttributesAsync(); - Assert.AreEqual("Dolly", snapshot.Metadata["Hello"]); - Assert.AreEqual("Ma", snapshot.Metadata["Yoyo"]); - Assert.IsFalse(snapshot.Metadata.ContainsKey("Marco")); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test conditional access on a blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobConditionalAccessAsync() - { - OperationContext operationContext = new OperationContext(); - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - await blob.CreateAsync(1024); - await blob.FetchAttributesAsync(); - - string currentETag = blob.Properties.ETag; - DateTimeOffset currentModifiedTime = blob.Properties.LastModified.Value; - - // ETag conditional tests - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue"; - await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(currentETag), null, null); - - await blob.FetchAttributesAsync(); - string newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - - blob.Metadata["ETagConditionalName"] = "ETagConditionalValue2"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(newETag), null, operationContext), - operationContext, - "If none match on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - string invalidETag = "\"0x10101010\""; - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfMatchCondition(invalidETag), null, operationContext), - operationContext, - "Invalid ETag on conditional test should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNoneMatchCondition(invalidETag), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - - // LastModifiedTime tests - currentModifiedTime = blob.Properties.LastModified.Value; - - blob.Metadata["DateConditionalName"] = "DateConditionalValue"; - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), - operationContext, - "IfModifiedSince conditional on current modified time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await blob.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); - - currentModifiedTime = blob.Properties.LastModified.Value; - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(pastTime), null, operationContext), - operationContext, - "IfNotModifiedSince conditional on past time should throw", - HttpStatusCode.PreconditionFailed, - "ConditionNotMet"); - - blob.Metadata["DateConditionalName"] = "DateConditionalValue2"; - - currentETag = blob.Properties.ETag; - await blob.SetMetadataAsync(AccessCondition.GenerateIfNotModifiedSinceCondition(currentModifiedTime), null, null); - - await blob.FetchAttributesAsync(); - newETag = blob.Properties.ETag; - Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test page blob methods on a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobMethodsOnBlockBlobAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - List blobs = await CreateBlobsAsync(container, 1, BlobType.BlockBlob); - CloudPageBlob blob = container.GetPageBlobReference(blobs.First()); - - OperationContext operationContext = new OperationContext(); - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.ClearPagesAsync(0, 512, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.GetPageRangesAsync(null /* offset */, null /* length */, null, null, operationContext), - operationContext, - "Page operations should fail on block blobs", - HttpStatusCode.Conflict, - "InvalidBlobType"); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test 512-byte page alignment")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobAlignmentAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudPageBlob blob = container.GetPageBlobReference("blob1"); - OperationContext operationContext = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.CreateAsync(511, null, null, operationContext), - operationContext, - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.CreateAsync(513, null, null, operationContext), - operationContext, - "Page operations that are not 512-byte aligned should fail", - HttpStatusCode.BadRequest); - - await blob.CreateAsync(512); - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(511); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, null, null, operationContext), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(513); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.WritePagesAsync(stream, 0, null, null, null, operationContext), - "Page operations that are not 512-byte aligned should fail"); - } - - using (MemoryStream stream = new MemoryStream()) - { - stream.SetLength(512); - await blob.WritePagesAsync(stream, 0, null); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Upload and download null/empty data")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobUploadDownloadNoDataAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob blob = container.GetPageBlobReference("blob"); - await TestHelper.ExpectedExceptionAsync( - async () => await blob.UploadFromStreamAsync(null), - "Uploading from a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.UploadFromStreamAsync(stream); - } - - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DownloadToStreamAsync(null), - "Downloading to a null stream should fail"); - - using (MemoryStream stream = new MemoryStream()) - { - await blob.DownloadToStreamAsync(stream); - Assert.AreEqual(0, stream.Length); - } - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CopyBlobTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CopyBlobTest.cs deleted file mode 100644 index a95f0c5fc477b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/CopyBlobTest.cs +++ /dev/null @@ -1,468 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class CopyBlobTest : BlobTestBase - { - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("CopyFromBlob with Unicode source blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CopyBlobUsingUnicodeBlobNameAsync() - { - string _unicodeBlobName = "繁体字14a6c"; - string _nonUnicodeBlobName = "sample_file"; - - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - CloudBlockBlob blobUnicodeSource = container.GetBlockBlobReference(_unicodeBlobName); - string data = "Test content"; - await UploadTextAsync(blobUnicodeSource, data, Encoding.UTF8); - CloudBlockBlob blobAsciiSource = container.GetBlockBlobReference(_nonUnicodeBlobName); - await UploadTextAsync(blobAsciiSource, data, Encoding.UTF8); - - //Copy blobs over - CloudBlockBlob blobAsciiDest = container.GetBlockBlobReference(_nonUnicodeBlobName + "_copy"); - string copyId = await blobAsciiDest.StartCopyFromBlobAsync(TestHelper.Defiddler(blobAsciiSource)); - await WaitForCopyAsync(blobAsciiDest); - - CloudBlockBlob blobUnicodeDest = container.GetBlockBlobReference(_unicodeBlobName + "_copy"); - copyId = await blobUnicodeDest.StartCopyFromBlobAsync(TestHelper.Defiddler(blobUnicodeSource)); - await WaitForCopyAsync(blobUnicodeDest); - - Assert.AreEqual(CopyStatus.Success, blobUnicodeDest.CopyState.Status); - Assert.AreEqual(blobUnicodeSource.Uri.AbsolutePath, blobUnicodeDest.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.TotalBytes); - Assert.AreEqual(data.Length, blobUnicodeDest.CopyState.BytesCopied); - Assert.AreEqual(copyId, blobUnicodeDest.CopyState.CopyId); - Assert.IsTrue(blobUnicodeDest.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await copy.AbortCopyAsync(copyId, null, null, opContext), - opContext, - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - await source.FetchAttributesAsync(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyTestWithMetadataOverrideAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - await source.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobCopyFromSnapshotTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudBlockBlob source = container.GetBlockBlobReference("source"); - - string data = "String data"; - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudBlockBlob snapshot = await source.CreateSnapshotAsync(); - - //Modify source - string newData = "Hello"; - source.Metadata["Test"] = "newvalue"; - await source.SetMetadataAsync(); - source.Properties.ContentMD5 = null; - await UploadTextAsync(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, await DownloadTextAsync(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, await DownloadTextAsync(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - await source.FetchAttributesAsync(); - await snapshot.FetchAttributesAsync(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudBlockBlob copy = container.GetBlockBlobReference("copy"); - await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, await DownloadTextAsync(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and then verify its contents, properties, and metadata")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - OperationContext opContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await copy.AbortCopyAsync(copyId, null, null, opContext), - opContext, - "Aborting a copy operation after completion should fail", - HttpStatusCode.Conflict, - "NoPendingCopyOperation"); - - await source.FetchAttributesAsync(); - Assert.IsNotNull(copy.Properties.ETag); - Assert.AreNotEqual(source.Properties.ETag, copy.Properties.ETag); - Assert.IsTrue(copy.Properties.LastModified > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyTestWithMetadataOverrideAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - copy.Metadata["Test2"] = "value2"; - string copyId = await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(source)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(source.Uri.AbsolutePath, copy.CopyState.Source.AbsolutePath); - Assert.AreEqual(data.Length, copy.CopyState.TotalBytes); - Assert.AreEqual(data.Length, copy.CopyState.BytesCopied); - Assert.AreEqual(copyId, copy.CopyState.CopyId); - Assert.IsTrue(copy.CopyState.CompletionTime > DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))); - - string copyData = await DownloadTextAsync(copy, Encoding.UTF8); - Assert.AreEqual(data, copyData, "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - await source.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = source.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value2", copy.Metadata["Test2"], false, "Copied metadata not same"); - Assert.IsFalse(copy.Metadata.ContainsKey("Test"), "Source Metadata should not appear in destination blob"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Copy a blob and override metadata during copy")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobCopyFromSnapshotTestAsync() - { - CloudBlobContainer container = GetRandomContainerReference(); - try - { - await container.CreateAsync(); - - CloudPageBlob source = container.GetPageBlobReference("source"); - - string data = new string('a', 512); - await UploadTextAsync(source, data, Encoding.UTF8); - - source.Metadata["Test"] = "value"; - await source.SetMetadataAsync(); - - CloudPageBlob snapshot = await source.CreateSnapshotAsync(); - - //Modify source - string newData = new string('b', 512); - source.Metadata["Test"] = "newvalue"; - await source.SetMetadataAsync(); - source.Properties.ContentMD5 = null; - await UploadTextAsync(source, newData, Encoding.UTF8); - - Assert.AreEqual(newData, await DownloadTextAsync(source, Encoding.UTF8), "Source is modified correctly"); - Assert.AreEqual(data, await DownloadTextAsync(snapshot, Encoding.UTF8), "Modifying source blob should not modify snapshot"); - - await source.FetchAttributesAsync(); - await snapshot.FetchAttributesAsync(); - Assert.AreNotEqual(source.Metadata["Test"], snapshot.Metadata["Test"], "Source and snapshot metadata should be independent"); - - CloudPageBlob copy = container.GetPageBlobReference("copy"); - await copy.StartCopyFromBlobAsync(TestHelper.Defiddler(snapshot)); - await WaitForCopyAsync(copy); - Assert.AreEqual(CopyStatus.Success, copy.CopyState.Status); - Assert.AreEqual(data, await DownloadTextAsync(copy, Encoding.UTF8), "Data inside copy of blob not similar"); - - await copy.FetchAttributesAsync(); - BlobProperties prop1 = copy.Properties; - BlobProperties prop2 = snapshot.Properties; - - Assert.AreEqual(prop1.CacheControl, prop2.CacheControl); - Assert.AreEqual(prop1.ContentEncoding, prop2.ContentEncoding); - Assert.AreEqual(prop1.ContentLanguage, prop2.ContentLanguage); - Assert.AreEqual(prop1.ContentMD5, prop2.ContentMD5); - Assert.AreEqual(prop1.ContentType, prop2.ContentType); - - Assert.AreEqual("value", copy.Metadata["Test"], false, "Copied metadata not same"); - - await copy.DeleteAsync(); - } - finally - { - container.DeleteIfExistsAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/LeaseTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/LeaseTests.cs deleted file mode 100644 index b1fd17a0febb6..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/LeaseTests.cs +++ /dev/null @@ -1,2926 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Blob.Protocol; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using Windows.Storage.Streams; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class LeaseTests : BlobTestBase - { - /// - /// The prefix to use for the current test. New containers and blobs in the root container begin with this prefix - /// to avoid conflicting with other tests or concurrent runs of the same test. This also allows a test to easily - /// clean itself up and to have a persistent recoverable state if a test fails. - /// - private string prefix; - - /// - /// The client for the blob service. - /// - private CloudBlobClient blobClient; - - /// - /// Create the given blob and, if necessary, its container. - /// - /// The blob to create. - internal static async Task CreateBlobAsync(ICloudBlob blob) - { - await blob.Container.CreateIfNotExistsAsync(); - await UploadTextAsync(blob, "LeaseTestBlobContent", Encoding.UTF8); - } - - /// - /// Get a reference to a container of the given name, prepending the current prefix. - /// - /// The name of the container to which the prefix will be prepended. - /// A reference to the container. - internal CloudBlobContainer GetContainerReference(string rootName) - { - return this.blobClient.GetContainerReference(string.Format("{0}-{1}", this.prefix, rootName)); - } - - [TestInitialize] - public void TestInitialize() - { - this.blobClient = GenerateCloudBlobClient(); - - // Create and log a new prefix for this test. - this.prefix = Guid.NewGuid().ToString("N"); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - // Retire this test's prefix. No other cleanup is done here. - this.prefix = null; - - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - /// - /// Deletes all containers beginning with the current prefix, and all blobs in the root container beginning with the current prefix. - /// Any existing lease is broken before the resource is deleted. All exceptions are ignored. - /// - internal async Task DeleteAllAsync() - { - try - { - // Delete all containers with prefix - ContainerResultSegment containers = await this.blobClient.ListContainersSegmentedAsync(this.prefix, ContainerListingDetails.None, null, null, null, null); - foreach (CloudBlobContainer container in containers.Results) - { - try - { - await container.BreakLeaseAsync(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - await container.DeleteAsync(); - } - catch (Exception) - { - } - } - - // Delete all blobs in root container with prefix - CloudBlobContainer rc = this.blobClient.GetRootContainerReference(); - BlobResultSegment blobs = await rc.ListBlobsSegmentedAsync(this.prefix, true, BlobListingDetails.None, null, null, null, null); - foreach (ICloudBlob blob in blobs.Results) - { - try - { - await blob.BreakLeaseAsync(TimeSpan.Zero); - } - catch (Exception) - { - } - - try - { - await blob.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots, null /* access conditions */, null /* options */, null); - } - catch (Exception) - { - } - } - } - catch (Exception) - { - } - } - - /// - /// Puts the lease on the given blob in an available state. - /// - /// The blob with the lease. - internal static async Task SetAvailableStateAsync(ICloudBlob blob) - { - bool shouldBreakFirst = false; - - OperationContext operationContext = new OperationContext(); - try - { - await blob.DeleteIfExistsAsync(DeleteSnapshotsOption.None, null, null, operationContext); - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - shouldBreakFirst = true; - } - else - { - throw; - } - } - - if (shouldBreakFirst) - { - await blob.BreakLeaseAsync(TimeSpan.Zero); - await blob.DeleteAsync(); - } - await CreateBlobAsync(blob); - } - - /// - /// Puts the lease on the given blob in a leased state. - /// - /// The blob with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static async Task SetLeasedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - await SetAvailableStateAsync(blob); - return await blob.AcquireLeaseAsync(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given blob in a renewed state. - /// - /// The blob with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static async Task SetRenewedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(blob, leaseTime); - await blob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a released state. - /// - /// The blob with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static async Task SetReleasedStateAsync(ICloudBlob blob, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(blob, leaseTime); - await blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a breaking state for 60 seconds. - /// - /// The blob with the lease. - /// The lease ID of the current (but breaking) lease. - internal static async Task SetBreakingStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to the break period expiring. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static async Task SetTimeBrokenStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - await Task.Delay(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given blob in a broken state due to a break period of zero. - /// - /// The blob with the lease. - /// The lease ID of the broken lease. - internal static async Task SetInstantBrokenStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, null /* infinite lease */); - await blob.BreakLeaseAsync(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given blob in an expired state. - /// - /// The blob with the lease. - /// The lease ID of the expired lease. - internal static async Task SetExpiredStateAsync(ICloudBlob blob) - { - string leaseId = await SetLeasedStateAsync(blob, TimeSpan.FromSeconds(15)); - await Task.Delay(TimeSpan.FromSeconds(17)); - return leaseId; - } - - /// - /// Puts the lease on the given container in an unleased state (either available or broken). - /// - /// The container with the lease. - internal static async Task SetUnleasedStateAsync(CloudBlobContainer container) - { - if (!await container.CreateIfNotExistsAsync()) - { - OperationContext operationContext = new OperationContext(); - try - { - await container.BreakLeaseAsync(TimeSpan.Zero, null, null, operationContext); - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseAlreadyBroken || - operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation) - { - } - else - { - throw; - } - } - } - } - - /// - /// Puts the lease on the given container in a leased state. - /// - /// The container with the lease. - /// The amount of time on the new lease. - /// The lease ID of the current lease. - internal static async Task SetLeasedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = Guid.NewGuid().ToString(); - await SetUnleasedStateAsync(container); - return await container.AcquireLeaseAsync(leaseTime, leaseId); - } - - /// - /// Puts the lease on the given container in a renewed state. - /// - /// The container with the lease. - /// The amount of time on the renewed lease. - /// The lease ID of the current lease. - internal static async Task SetRenewedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(container, leaseTime); - await container.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a released state. - /// - /// The container with the lease. - /// The amount of time on the released lease. - /// The lease ID of the released lease. - internal static async Task SetReleasedStateAsync(CloudBlobContainer container, TimeSpan? leaseTime) - { - string leaseId = await SetLeasedStateAsync(container, leaseTime); - await container.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a breaking state for 60 seconds. - /// - /// The container with the lease. - /// The lease ID of the current (but breaking) lease. - internal static async Task SetBreakingStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to the break period expiring. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static async Task SetTimeBrokenStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - await Task.Delay(TimeSpan.FromSeconds(2)); - return leaseId; - } - - /// - /// Puts the lease on the given container in a broken state due to a break period of zero. - /// - /// The container with the lease. - /// The lease ID of the broken lease. - internal static async Task SetInstantBrokenStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, null /* infinite lease */); - await container.BreakLeaseAsync(TimeSpan.Zero); - return leaseId; - } - - /// - /// Puts the lease on the given container in an expired state. - /// - /// The container with the lease. - /// The lease ID of the expired lease. - internal static async Task SetExpiredStateAsync(CloudBlobContainer container) - { - string leaseId = await SetLeasedStateAsync(container, TimeSpan.FromSeconds(15)); - await Task.Delay(TimeSpan.FromSeconds(17)); - return leaseId; - } - - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobAcquireLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await SetExpiredStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - await SetInstantBrokenStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobRenewLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(15)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.BlobAcquireRenewLeaseTestAsync(leasedBlob, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await this.DeleteAllAsync(); - } - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. (This last feature is necessary for infinite leases.) - /// - /// The blob to test. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal async Task BlobAcquireRenewLeaseTestAsync(ICloudBlob leasedBlob, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - OperationContext operationContext = new OperationContext(); - DateTime beginTime = DateTime.UtcNow; - - bool testOver = false; - do - { - try - { - // Attempt to write to the blob with no lease ID. - await leasedBlob.SetMetadataAsync(null, null, operationContext); - - // The write succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Writes should not succeed while lease is present."); - - // Since the lease has expired, the test is over. - testOver = true; - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Writes should succeed after a lease expires."); - } - - // End the test early if necessary. - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - // Some other error occurred. Rethrow the exception. - throw; - } - } - - // Attempt to read from the blob. This should always succeed. - await leasedBlob.FetchAttributesAsync(); - - // Wait 1 second before trying again. - if (!testOver) - { - await Task.Delay(TimeSpan.FromSeconds(1)); - } - } - while (!testOver); - - // The lease expired. Write to and read from the blob once more. - await leasedBlob.SetMetadataAsync(); - await leasedBlob.FetchAttributesAsync(); - } - - [TestMethod] - [Description("Test blob leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeaseInvalidInputTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - await CreateBlobAsync(leasedBlob); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(1), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(14), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(61), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, invalidLeaseId, null, null, operationContext), - operationContext, - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the blob is leased - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(null /* access condition */, null, operationContext), - "renew with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateEmptyCondition(), null, operationContext), - "renew with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, null /* access condition */, null, operationContext), - "change with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateEmptyCondition(), null, operationContext), - "change with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - "change a lease with no proposed lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(null /* access condition */, null, operationContext), - "release with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateEmptyCondition(), null, operationContext), - "release with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(-1), null, null, operationContext), - "break with negative break time"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(61), null, null, operationContext), - operationContext, - "break with too large break time", - HttpStatusCode.BadRequest); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobAcquireLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Acquire the lease while in available state, make idempotent call - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - leaseId2 = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId, null, null, operationContext), - operationContext, - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - await SetAvailableStateAsync(leasedBlob); - leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobRenewLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Renew lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = await SetExpiredStateAsync(leasedBlob); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = await SetExpiredStateAsync(leasedBlob); - string content = await DownloadTextAsync(leasedBlob, Encoding.UTF8); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = await SetExpiredStateAsync(leasedBlob); - await leasedBlob.SetMetadataAsync(); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew an expired lease that has been modified", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew finite lease - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = await SetReleasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = await SetReleasedStateAsync(leasedBlob, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobChangeLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Change lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, operationContext), - operationContext, - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobReleaseLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Release lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = await SetBreakingStateAsync(leasedBlob); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = await SetBreakingStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobBreakLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Break lease in available state - await SetAvailableStateAsync(leasedBlob); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = await SetBreakingStateAsync(leasedBlob); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = await SetBreakingStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break finite lease (longer than lease time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(50)); - leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break instant broken lease (default break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(null /* default break time */); - - // Break instant broken lease (nonzero break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = await SetInstantBrokenStateAsync(leasedBlob); - await leasedBlob.BreakLeaseAsync(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedBlob.BreakLeaseAsync(null /* default break time */, null, null, operationContext), - operationContext, - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Tests blob write and delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeasedWriteTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob sourceBlob = leasedBlob.Container.GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // Verify that blob creation fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // BlobCreateExpectLeaseFailure(leasedBlob, sourceBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create blob using a lease"); - - // From available state, verify that writes/deletes that pass a lease fail if none is present. - await SetAvailableStateAsync(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write blob using a lease when no lease is held"); - - // From leased state, verify that writes/deletes without a lease do not succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write blob using no lease when a lease is held"); - - // From leased state, verify that writes/deletes with the wrong lease fail. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - await this.BlobWriteExpectLeaseFailureAsync(leasedBlob, sourceBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write blob using a lease when a different lease is held"); - - // From leased state, verify that writes/deletes with the right lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - await this.BlobWriteExpectLeaseSuccessAsync(leasedBlob, sourceBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test blob write and creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobWriteExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - await this.BlobCreateExpectLeaseFailureAsync(testBlob, sourceBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.SetMetadataAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Properties)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test blob creation, expecting lease failure. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobCreateExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob sourceBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await UploadTextAsync(testBlob, "No Dice", Encoding.UTF8, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Upload Text)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.StartCopyFromBlobAsync(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Copy From)", - expectedStatusCode, - expectedErrorCode); - - Stream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, operationContext); - Stream stream = writeStream; - await TestHelper.ExpectedExceptionAsync( - async () => - { - stream.WriteByte(0); - await stream.FlushAsync(); - }, - operationContext, - description + " (Write Stream)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test blob writing, expecting success. - /// - /// The blob to test. - /// A blob to use as the source of a copy. - /// The access condition to use. - private async Task BlobWriteExpectLeaseSuccessAsync(CloudBlockBlob testBlob, ICloudBlob sourceBlob, AccessCondition testAccessCondition) - { - await testBlob.SetMetadataAsync(testAccessCondition, null /* options */, null); - await testBlob.SetPropertiesAsync(testAccessCondition, null /* options */, null); - await UploadTextAsync(testBlob, "No Problem", Encoding.UTF8, testAccessCondition, null /* options */, null); - await testBlob.StartCopyFromBlobAsync(TestHelper.Defiddler(sourceBlob.Uri), null /* source access condition */, testAccessCondition, null /* options */, null); - - while (testBlob.CopyState.Status == CopyStatus.Pending) - { - await Task.Delay(1000); - await testBlob.FetchAttributesAsync(); - } - - Stream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, null); - Stream stream = writeStream; - stream.WriteByte(0); - await stream.FlushAsync(); - - await testBlob.DeleteAsync(DeleteSnapshotsOption.None, testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Tests blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeasedReadTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - CloudBlockBlob targetBlob = leasedBlob.Container.GetBlockBlobReference("TargetBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - // From available state, verify that reads that pass a lease fail if none is present - await SetAvailableStateAsync(leasedBlob); - testAccessCondition.LeaseId = fakeLease; - await this.BlobReadExpectLeaseFailureAsync(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read blob using a lease when no lease is held"); - - // Verify that reads without a lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = null; - await this.BlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = fakeLease; - await this.BlobReadExpectLeaseFailureAsync(leasedBlob, targetBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - testAccessCondition.LeaseId = leaseId; - await this.BlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test blob reads, expecting lease failure. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlobReadExpectLeaseFailureAsync(CloudBlockBlob testBlob, CloudBlockBlob targetBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Create Snapshot)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await DownloadTextAsync(testBlob, Encoding.UTF8, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Download Text)", - expectedStatusCode, - expectedErrorCode); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.OpenReadAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Read Stream)", - expectedStatusCode/*, - expectedErrorCode*/); - } - - /// - /// Test blob reads, expecting success. - /// - /// The blob to test. - /// The blob to use for the target of copy operations. - /// The access condition to use. - private async Task BlobReadExpectLeaseSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.FetchAttributesAsync(testAccessCondition, null /* options */, null); - await (await testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, null)).DeleteAsync(); - await DownloadTextAsync(testBlob, Encoding.UTF8, testAccessCondition, null /* options */, null); - - Stream readStream = await testBlob.OpenReadAsync(testAccessCondition, null /* options */, null); - Stream stream = readStream; - stream.ReadByte(); - } - - [TestMethod] - [Description("Tests page blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobLeasedWriteTestsAsync() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Verify that creating the page blob fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testAccessCondition.LeaseId = fakeLease; - // PageBlobCreateExpectLeaseFailure(leasedBlob, testAccessCondition, BlobErrorCodeStrings.LeaseNotPresent, "create page blob using a lease"); - - // Create a page blob - testAccessCondition.LeaseId = null; - await PageBlobCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // From available state, verify that writing the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "write page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "write page blob with no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await PageBlobWriteExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "write page blob using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await PageBlobWriteExpectSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test page blob creation, expecting lease failure. - /// - /// The page blob to test. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobCreateExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.CreateAsync(8 * 512, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Create Page Blob)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob writes, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobWriteExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - await PageBlobCreateExpectLeaseFailureAsync(testBlob, testAccessCondition, expectedStatusCode, expectedErrorCode, description); - - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.ClearPagesAsync(512, 512, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Clear Pages)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.WritePagesAsync(pageStream, 512, null, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Write Pages)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob creation, expecting success. - /// - /// The page blob. - /// The test access condition. - private async Task PageBlobCreateExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.CreateAsync(8 * 512, testAccessCondition, null /* options */, null); - } - - /// - /// Test page blob writes, expecting success. - /// - /// The page blob. - /// The access condition to use. - private async Task PageBlobWriteExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - byte[] buffer = new byte[4 * 512]; - Random random = new Random(); - random.NextBytes(buffer); - Stream pageStream = new MemoryStream(buffer); - - await testBlob.ClearPagesAsync(512, 512, testAccessCondition, null /* options */, null); - await testBlob.WritePagesAsync(pageStream, 512, null, testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Tests page blob read APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task PageBlobLeasedReadTestsAsync() - { - CloudPageBlob leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Create a page blob - testAccessCondition.LeaseId = null; - await PageBlobCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reading the page blob fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await PageBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read page blob with a lease when no lease is held"); - - // Acquire a lease - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease succeed. - testAccessCondition.LeaseId = null; - await PageBlobReadExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await PageBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read page blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await PageBlobReadExpectSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test page blob reads, expecting lease failure. - /// - /// The page blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task PageBlobReadExpectLeaseFailureAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.GetPageRangesAsync(null /* offset */, null /* length */, testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Get Page Ranges)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test page blob reads, expecting success. - /// - /// The page blob. - /// The access condition to use. - private async Task PageBlobReadExpectSuccessAsync(CloudPageBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.GetPageRangesAsync(null /* offset */, null /* length */, testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Tests block blob write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedWriteTestsAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - await leasedBlob.Container.CreateAsync(); - - // Verify that creating the first block fails when a lease is supplied. - // RdBug 243397: Blob creation operations should fail when lease id is specified and blob does not exist - // testOptions.LeaseId = fakeLease; - // await BlockCreateExpectLeaseFailureAsync(leasedBlob, testOptions, BlobErrorCodeStrings.LeaseNotPresent, "create initial block using a lease"); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - - // Verify that creating an additional block fails when a lease is supplied. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "create additional block using a lease"); - - // Verify that block list writes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "set initial block list using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that writes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "set initial block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "set initial block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = null; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "create block using no lease when a lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "update block list using no lease when a lease is held"); - - // Verify that writes with the wrong lease fail, with the block list already set. - testAccessCondition.LeaseId = fakeLease; - await BlockCreateExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "create block using a lease when a different lease is held"); - await BlockBlobWriteExpectLeaseFailureAsync(leasedBlob, blockList, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "update block list using a lease when a different lease is held"); - - // Verify that writes with the right lease succeed, with the block list already set. - testAccessCondition.LeaseId = leaseId; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test block creation, expecting lease failure. - /// - /// The block blob in which to attempt to create a block. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockCreateExpectLeaseFailureAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await BlockCreateAsync(testBlob, testAccessCondition, operationContext), - operationContext, - description + " (Put Block)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob creation (block list setting), expecting lease failure. - /// - /// The block blob. - /// An appropriate block list to set. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockBlobWriteExpectLeaseFailureAsync(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.PutBlockListAsync(blockList, testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Put Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block creation, expecting success. - /// - /// The block blob. - /// The test access condition. - /// The name of the new block. - private async Task BlockCreateExpectSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - return await BlockCreateAsync(testBlob, testAccessCondition, null); - } - - /// - /// Create a block with a random name. - /// - /// The block blob. - /// The access condition. - /// The name of the new block. - private async Task BlockCreateAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, OperationContext operationContext) - { - byte[] buffer = new byte[4 * 1024]; - Random random = new Random(); - random.NextBytes(buffer); - string blockId = Guid.NewGuid().ToString("N"); - Stream blockData = new MemoryStream(buffer); - await testBlob.PutBlockAsync(blockId, blockData, null /* content MD5 */, testAccessCondition, null /* options */, operationContext); - - return blockId; - } - - /// - /// Test block blob creation (set block list), expecting success. - /// - /// The block blob. - /// The block list to set. - /// The access condition to use. - private async Task BlockBlobWriteExpectSuccessAsync(CloudBlockBlob testBlob, IEnumerable blockList, AccessCondition testAccessCondition) - { - await testBlob.PutBlockListAsync(blockList, testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Tests block blob read APIs in the presence of a lease on a blob with no block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedReadTestsWithoutListAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - - await leasedBlob.Container.CreateAsync(); - - // Create a block - testAccessCondition.LeaseId = null; - await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Tests block blob read APIs in the presence of a lease on a blob with a block list.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlockBlobLeasedReadTestsWithListAsync() - { - CloudBlockBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - string leaseId; - List blockList = new List(); - - await leasedBlob.Container.CreateAsync(); - - // Create a block - testAccessCondition.LeaseId = null; - blockList.Add(await BlockCreateExpectSuccessAsync(leasedBlob, testAccessCondition)); - - // Put the block list - testAccessCondition.LeaseId = null; - await BlockBlobWriteExpectSuccessAsync(leasedBlob, blockList, testAccessCondition); - - // Verify that reads without a lease succeed - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with a lease fail - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithBlobOperation, "read block blob using a lease when no lease is held"); - - // Acquire a lease - testAccessCondition.LeaseId = null; - leaseId = await leasedBlob.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads without a lease still succeed. - testAccessCondition.LeaseId = null; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - // Verify that reads with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await BlockBlobReadExpectLeaseFailureAsync(leasedBlob, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithBlobOperation, "read block blob using a lease when a different lease is held"); - - // Verify that reads with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await BlockBlobReadExpectLeaseSuccessAsync(leasedBlob, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test block blob reads, expecting lease failure. - /// - /// The block blob. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task BlockBlobReadExpectLeaseFailureAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testBlob.DownloadBlockListAsync(BlockListingFilter.Committed, testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Download Block List)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test block blob reads, expecting success. - /// - /// The block blob. - /// The access condition to use. - private async Task BlockBlobReadExpectLeaseSuccessAsync(CloudBlockBlob testBlob, AccessCondition testAccessCondition) - { - await testBlob.DownloadBlockListAsync(BlockListingFilter.Committed, testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Test reading the blob lease status and state after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task BlobLeaseStatusTestAsync() - { - string leaseId; - ICloudBlob leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); - - // Check uninitialized lease status - await SetAvailableStateAsync(leasedBlob); - Assert.AreEqual(LeaseStatus.Unspecified, leasedBlob.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedBlob.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedBlob.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - await SetAvailableStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - await SetRenewedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - await SetRenewedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); - await leasedBlob.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = await SetLeasedStateAsync(leasedBlob, TimeSpan.FromSeconds(45)); - await leasedBlob.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - await SetBreakingStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - await SetTimeBrokenStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - await SetTimeBrokenStateAsync(leasedBlob); - await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, null /*proposed lease ID */); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - await SetInstantBrokenStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - await SetExpiredStateAsync(leasedBlob); - await this.CheckLeaseStatusAsync(leasedBlob, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - await this.DeleteAllAsync(); - } - - /// - /// Checks the lease status of a blob, both from its attributes and from a blob listing. - /// - /// The blob to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private async Task CheckLeaseStatusAsync( - ICloudBlob blob, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - await blob.FetchAttributesAsync(); - Assert.AreEqual(expectedStatus, blob.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, blob.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, blob.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - BlobResultSegment blobs = await blob.Container.ListBlobsSegmentedAsync(blob.Name, true, BlobListingDetails.None, null, null, null, null); - BlobProperties propertiesInListing = (from ICloudBlob b in blobs.Results - where b.Name == blob.Name - select b.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListBlobs)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListBlobs)"); - } - - [TestMethod] - [Description("Test lease acquire semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerAcquireLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-4"); // make sure we use a new container - await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-5"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-6"); // make sure we use a new container - await SetExpiredStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-7"); // make sure we use a new container - await SetInstantBrokenStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(15), leaseId); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease renew semantics with various valid lease durations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerRenewLeaseSemanticTestsAsync() - { - TimeSpan tolerance = TimeSpan.FromSeconds(2); - string leaseId; - - CloudBlobContainer leasedContainer; - - leasedContainer = this.GetContainerReference("leased-container-1"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(15)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-2"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(70), tolerance); - - leasedContainer = this.GetContainerReference("leased-container-3"); // make sure we use a new container - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - await this.ContainerAcquireRenewLeaseTestAsync(leasedContainer, null /* infinite lease */, TimeSpan.FromSeconds(70), tolerance); - - await this.DeleteAllAsync(); - } - - /// - /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. - /// The test is cut short once the testLength time has elapsed. - /// - /// The container. - /// The duration of the lease. - /// The maximum length of time to run the test. - /// The allowed lease time error. - internal async Task ContainerAcquireRenewLeaseTestAsync(CloudBlobContainer leasedContainer, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) - { - OperationContext operationContext = new OperationContext(); - DateTime beginTime = DateTime.UtcNow; - - while (true) - { - try - { - // Attempt to delete the container with no lease ID. - await leasedContainer.DeleteAsync(null, null, operationContext); - - // The delete succeeded, which means that the lease must have expired. - - // If the lease was infinite then there is an error because it should not have expired. - Assert.IsNotNull(duration, "An infinite lease should not expire."); - - // The lease should be past its expiration time. - Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Deletes should not succeed while lease is present."); - - // Since the lease has expired (and the container was deleted), the test is over. - return; - } - catch (Exception) - { - if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) - { - // We got this error because the lease has not expired yet. - - // Make sure the lease is not past its expiration time yet. - DateTime currentTime = DateTime.UtcNow; - if (duration.HasValue) - { - Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Deletes should succeed after a lease expires."); - } - - // End the test early if necessary - if (currentTime - beginTime > testLength) - { - // The lease has not expired, but we're not waiting any longer. - return; - } - } - else - { - throw; - } - } - - // Attempt to write to and read from the container. This should always succeed. - await leasedContainer.SetMetadataAsync(); - await leasedContainer.FetchAttributesAsync(); - - // Wait 1 second before trying again. - await Task.Delay(TimeSpan.FromSeconds(1)); - } - } - - [TestMethod] - [Description("Test container leasing with invalid inputs")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeaseInvalidInputTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string invalidLeaseId = "invalid"; - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - await leasedContainer.CreateAsync(); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.Zero, null /* proposed lease ID */), - "acquire a lease with 0 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(-1), null /* proposed lease ID */), - "acquire a lease with -1 duration"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(1), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease with 1 s duration", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(14), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too short", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(TimeSpan.FromSeconds(61), null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease that is too long", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, invalidLeaseId, null, null, operationContext), - operationContext, - "acquire a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - // The following tests assume that the container is leased - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(null /* access condition */), - "renew with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateEmptyCondition()), - "renew with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, null /* access condition */), - "change with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateEmptyCondition()), - "change with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(invalidLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a lease with an invalid proposed lease ID", - HttpStatusCode.BadRequest); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(null /* proposed lease ID */, AccessCondition.GenerateLeaseCondition(leaseId)), - "change a lease with no proposed lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(null /* access condition */), - "release with null access condition"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateEmptyCondition()), - "release with no lease ID"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(-1)), - "break with negative break time"); - - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(61), null, null, operationContext), - operationContext, - "break with too large break time", - HttpStatusCode.BadRequest); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease acquire semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerAcquireLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Acquire the lease while in available state, make idempotent call - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - leaseId2 = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - Assert.AreEqual(leaseId, leaseId2); - - // Acquire the lease while in leased state (conflict) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while in leased state (conflict)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while breaking (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId, null, null, operationContext), - operationContext, - "acquire a lease while in the breaking state (same ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeAcquired); - - // Acquire the lease while breaking (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId, null, null, operationContext), - operationContext, - "acquire a lease while breaking (different ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Acquire the lease while in broken state (same ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in broken state (new ID), make idempotent call - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire the lease while in released state (same ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, leaseId); - - // Acquire the lease while in released state (new ID), make idempotent call - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); - - // Acquire with no proposed ID (non-idempotent) - await SetUnleasedStateAsync(leasedContainer); - leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /* proposed lease ID */, null, null, operationContext), - operationContext, - "acquire a lease twice with no proposed lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseAlreadyPresent); - - // Delete the blob - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease renew semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerRenewLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Renew lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the available state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew infinite lease - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew infinite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew an infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease (wrong lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released infinite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released lease - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew expired lease - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after read - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.FetchAttributesAsync(); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew expired lease after write - leaseId = await SetExpiredStateAsync(leasedContainer); - await leasedContainer.SetMetadataAsync(); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Renew finite lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (wrong ID) - leaseId = await SetReleasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a released finite lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew released finite lease (right ID) - leaseId = await SetReleasedStateAsync(leasedContainer, TimeSpan.FromSeconds(60)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a released finite lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a lease while in the breaking state", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Renew broken lease (same ID) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "renew a broken lease with the same lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBrokenAndCannotBeRenewed); - - // Renew broken lease (different ID) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "renew a broken lease with a different lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease change semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerChangeLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string proposedLeaseId2 = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - string leaseId2; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Change lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change leased lease, with idempotent change - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - - // Change a leased lease, with same proposed ID but different lease ID - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId)); - - // Change lease (wrong lease specified) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a lease using the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change released lease - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change released lease (to previous lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a released lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change a breaking lease (same ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a breaking lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIsBreakingAndCannotBeChanged); - - // Change a breaking lease (different ID) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "change a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Change broken lease - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(proposedLeaseId, AccessCondition.GenerateLeaseCondition(leaseId2), null, operationContext), - operationContext, - "change a broken lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Change broken lease (to previous lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ChangeLeaseAsync(leaseId, AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "change a broken lease (to previous lease)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease release semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerReleaseLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string unknownLeaseId = Guid.NewGuid().ToString(); - string leaseId; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Release lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease when no lease is held", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (wrong lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease (right lease) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release lease in released state (old lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, operationContext), - operationContext, - "release a released lease (using previous lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release lease in released state (unknown lease) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a released lease (using wrong lease ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release breaking lease (right lease) - leaseId = await SetBreakingStateAsync(leasedContainer); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release breaking lease (wrong lease) - leaseId = await SetBreakingStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a breaking lease (with wrong ID)", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - // Release broken lease (right lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); - - // Release broken lease (wrong lease) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(unknownLeaseId), null, operationContext), - operationContext, - "release a broken lease with the wrong lease ID", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseIdMismatchWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Test lease break semantics from various lease states")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerBreakLeaseStateTestsAsync() - { - OperationContext operationContext = new OperationContext(); - string proposedLeaseId = Guid.NewGuid().ToString(); - string leaseId; - TimeSpan leaseTime; - - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Break lease in available state - await SetUnleasedStateAsync(leasedContainer); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a lease when no lease is present", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - // Break infinite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break infinite lease (1 second break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break infinite lease (60 seconds break time) - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break breaking lease (zero break time) - leaseId = await SetBreakingStateAsync(leasedContainer); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break breaking lease (default break time) - leaseId = await SetBreakingStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break finite lease (longer than lease time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(60)); - - // Break finite lease (zero break time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - Assert.AreEqual(TimeSpan.Zero, leaseTime); - - // Break finite lease (default break time) - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(50)); - leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break broken lease (default break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(null /* default break period */); - - // Break instant broken lease (nonzero break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(TimeSpan.FromSeconds(1)); - - // Break instant broken lease (zero break time) - leaseId = await SetInstantBrokenStateAsync(leasedContainer); - await leasedContainer.BreakLeaseAsync(TimeSpan.Zero); - - // Break released lease (default break time) - leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await TestHelper.ExpectedExceptionAsync( - async () => await leasedContainer.BreakLeaseAsync(null /* default break period */, null, null, operationContext), - operationContext, - "break a released lease", - HttpStatusCode.Conflict, - BlobErrorCodeStrings.LeaseNotPresentWithLeaseOperation); - - await this.DeleteAllAsync(); - } - - [TestMethod] - [Description("Tests container delete APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeasedDeleteTestsAsync() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - - // Create the container - await leasedContainer.CreateAsync(); - - // Verify that deletes that pass a lease fail if none is present. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "delete container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = await leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that deletes without a lease do not succeed. - testAccessCondition.LeaseId = null; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMissing, "delete container using no lease when a lease is held"); - - // Verify that deletes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerDeleteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "delete container using a lease when a different lease is held"); - - // Verify that deletes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await this.ContainerDeleteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test container deletion, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task ContainerDeleteExpectLeaseFailureAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.DeleteAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Delete)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container deletion, expecting success. - /// - /// The container. - /// The access condition to use. - private async Task ContainerDeleteExpectLeaseSuccessAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - await testContainer.DeleteAsync(testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Tests container read and write APIs in the presence of a lease.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeasedReadWriteTestsAsync() - { - CloudBlobContainer leasedContainer = this.GetContainerReference("leased-container"); - AccessCondition testAccessCondition = AccessCondition.GenerateEmptyCondition(); - string fakeLease = Guid.NewGuid().ToString(); - await leasedContainer.CreateAsync(); - - // Verify that reads and writes that pass a lease fail if none is present - testAccessCondition.LeaseId = fakeLease; - await this.ContainerReadWriteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseNotPresentWithContainerOperation, "read/write container using a lease when no lease is held"); - - // Acquire a lease - string leaseId = await leasedContainer.AcquireLeaseAsync(null /* lease duration */, null /* proposed lease ID */); - - // Verify that reads and writes without a lease succeed. - testAccessCondition.LeaseId = null; - await this.ContainerReadWriteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - // Verify that reads and writes with the wrong lease fail. - testAccessCondition.LeaseId = fakeLease; - await this.ContainerReadWriteExpectLeaseFailureAsync(leasedContainer, testAccessCondition, HttpStatusCode.PreconditionFailed, BlobErrorCodeStrings.LeaseIdMismatchWithContainerOperation, "read/write container using a lease when a different lease is held"); - - // Verify that reads and writes with the right lease succeed. - testAccessCondition.LeaseId = leaseId; - await this.ContainerReadWriteExpectLeaseSuccessAsync(leasedContainer, testAccessCondition); - - await this.DeleteAllAsync(); - } - - /// - /// Test container reads and writes, expecting lease failure. - /// - /// The container. - /// The failing access condition to use. - /// The expected error code. - /// The reason why these calls should fail. - private async Task ContainerReadWriteExpectLeaseFailureAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) - { - OperationContext operationContext = new OperationContext(); - - // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + "(Fetch Attributes)", - HttpStatusCode.PreconditionFailed); - - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Get Permissions)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Metadata)", - expectedStatusCode, - expectedErrorCode); - await TestHelper.ExpectedExceptionAsync( - async () => await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, operationContext), - operationContext, - description + " (Set Permissions)", - expectedStatusCode, - expectedErrorCode); - } - - /// - /// Test container reads and writes, expecting success. - /// - /// The container. - /// The access condition to use. - private async Task ContainerReadWriteExpectLeaseSuccessAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition) - { - await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null); - await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null); - await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null); - await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null); - } - - [TestMethod] - [Description("Test reading the container lease status after various lease actions.")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ContainerLeaseStatusTestAsync() - { - string leaseId; - CloudBlobContainer leasedContainer = this.GetContainerReference("lease-tests"); - - // Check uninitialized lease status - await SetUnleasedStateAsync(leasedContainer); - Assert.AreEqual(LeaseStatus.Unspecified, leasedContainer.Properties.LeaseStatus, "uninitialized lease status"); - Assert.AreEqual(LeaseState.Unspecified, leasedContainer.Properties.LeaseState, "uninitialized lease state"); - Assert.AreEqual(LeaseDuration.Unspecified, leasedContainer.Properties.LeaseDuration, "uninitialized lease duration"); - - // Check lease status in initial state - await SetUnleasedStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "initial lease state"); - - // Check lease status after acquiring an infinite lease - await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after acquire lease"); - - // Check lease status after acquiring a finite lease - await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after acquire lease"); - - // Check lease status after renewing an infinite lease - await SetRenewedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after renew lease"); - - // Check lease status after renewing a finite lease - await SetRenewedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after renew lease"); - - // Check lease status after changing an infinite lease - leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); - await leasedContainer.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after change lease"); - - // Check lease status after changing a finite lease - leaseId = await SetLeasedStateAsync(leasedContainer, TimeSpan.FromSeconds(45)); - await leasedContainer.ChangeLeaseAsync(Guid.NewGuid().ToString(), AccessCondition.GenerateLeaseCondition(leaseId)); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Fixed, "after change lease"); - - // Check lease status after releasing a lease - await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Available, LeaseDuration.Unspecified, "after release lease"); - - // Check lease status while infinite lease is breaking - await SetBreakingStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Breaking, LeaseDuration.Unspecified, "while lease is breaking"); - - // Check lease status after lease breaks - await SetTimeBrokenStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after break time elapses"); - - // Check lease status after (infinite) acquire after break - await SetTimeBrokenStateAsync(leasedContainer); - await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, null /*proposed lease ID */); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Locked, LeaseState.Leased, LeaseDuration.Infinite, "after second acquire lease"); - - // Check lease status after instant break with infinite lease - await SetInstantBrokenStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Broken, LeaseDuration.Unspecified, "after instant break lease"); - - // Check lease status after lease expires - await SetExpiredStateAsync(leasedContainer); - await this.CheckLeaseStatusAsync(leasedContainer, LeaseStatus.Unlocked, LeaseState.Expired, LeaseDuration.Unspecified, "after lease expires"); - - await this.DeleteAllAsync(); - } - - /// - /// Checks the lease status of a container, both from its attributes and from a container listing. - /// - /// The container to test. - /// The expected lease status. - /// The expected lease state. - /// The expected lease duration. - /// A description of the circumstances that lead to the expected status. - private async Task CheckLeaseStatusAsync( - CloudBlobContainer container, - LeaseStatus expectedStatus, - LeaseState expectedState, - LeaseDuration expectedDuration, - string description) - { - await container.FetchAttributesAsync(); - Assert.AreEqual(expectedStatus, container.Properties.LeaseStatus, "LeaseStatus mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedState, container.Properties.LeaseState, "LeaseState mismatch: " + description + " (from FetchAttributes)"); - Assert.AreEqual(expectedDuration, container.Properties.LeaseDuration, "LeaseDuration mismatch: " + description + " (from FetchAttributes)"); - - ContainerResultSegment containers = await this.blobClient.ListContainersSegmentedAsync(container.Name, ContainerListingDetails.None, null, null, null, null); - BlobContainerProperties propertiesInListing = (from CloudBlobContainer c in containers.Results - where c.Name == container.Name - select c.Properties).Single(); - - Assert.AreEqual(expectedStatus, propertiesInListing.LeaseStatus, "LeaseStatus mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedState, propertiesInListing.LeaseState, "LeaseState mismatch: " + description + " (from ListContainers)"); - Assert.AreEqual(expectedDuration, propertiesInListing.LeaseDuration, "LeaseDuration mismatch: " + description + " (from ListContainers)"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/MD5FlagsTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/MD5FlagsTest.cs deleted file mode 100644 index 24c9ef31bce5c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/MD5FlagsTest.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class MD5FlagsTest : BlobTestBase - { - [TestMethod] - [Description("Test all MD5 flags")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void WindowsPhoneDoesNotSupportMD5() - { - BlobRequestOptions options = new BlobRequestOptions(); - Assert.ThrowsException( - () => options.DisableContentMD5Validation = false, - "MD5 flags should not work on Windows Phone"); - Assert.ThrowsException( - () => options.UseTransactionalMD5 = true, - "MD5 flags should not work on Windows Phone"); - Assert.ThrowsException( - () => options.StoreBlobContentMD5 = true, - "MD5 flags should not work on Windows Phone"); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/SASTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/SASTests.cs deleted file mode 100644 index 0290883e404f5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Blob/SASTests.cs +++ /dev/null @@ -1,296 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using System; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Blob -{ - [TestClass] - public class SASTests : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public void TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - this.testContainer.CreateAsync().Wait(); - - if (TestBase.BlobBufferManager != null) - { - TestBase.BlobBufferManager.OutstandingBufferCount = 0; - } - } - - [TestCleanup] - public void TestCleanup() - { - this.testContainer.DeleteAsync().Wait(); - this.testContainer = null; - if (TestBase.BlobBufferManager != null) - { - Assert.AreEqual(0, TestBase.BlobBufferManager.OutstandingBufferCount); - } - } - - private static async Task TestAccessAsync(string sasToken, SharedAccessBlobPermissions permissions, CloudBlobContainer container, ICloudBlob blob) - { - OperationContext operationContext = new OperationContext(); - StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ? - new StorageCredentials() : - new StorageCredentials(sasToken); - - if (container != null) - { - container = new CloudBlobContainer(container.Uri, credentials); - if (blob.BlobType == BlobType.BlockBlob) - { - blob = container.GetBlockBlobReference(blob.Name); - } - else - { - blob = container.GetPageBlobReference(blob.Name); - } - } - else - { - if (blob.BlobType == BlobType.BlockBlob) - { - blob = new CloudBlockBlob(blob.Uri, credentials); - } - else - { - blob = new CloudPageBlob(blob.Uri, credentials); - } - } - - if (container != null) - { - if ((permissions & SharedAccessBlobPermissions.List) == SharedAccessBlobPermissions.List) - { - await container.ListBlobsSegmentedAsync(null); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, null, null, null, operationContext), - operationContext, - "List blobs while SAS does not allow for listing", - HttpStatusCode.NotFound); - } - } - - if ((permissions & SharedAccessBlobPermissions.Read) == SharedAccessBlobPermissions.Read) - { - await blob.FetchAttributesAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.FetchAttributesAsync(null, null, operationContext), - operationContext, - "Fetch blob attributes while SAS does not allow for reading", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Write) == SharedAccessBlobPermissions.Write) - { - await blob.SetMetadataAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.SetMetadataAsync(null, null, operationContext), - operationContext, - "Set blob metadata while SAS does not allow for writing", - HttpStatusCode.NotFound); - } - - if ((permissions & SharedAccessBlobPermissions.Delete) == SharedAccessBlobPermissions.Delete) - { - await blob.DeleteAsync(); - } - else - { - await TestHelper.ExpectedExceptionAsync( - async () => await blob.DeleteAsync(DeleteSnapshotsOption.None, null, null, operationContext), - operationContext, - "Delete blob while SAS does not allow for deleting", - HttpStatusCode.NotFound); - } - } - - private static async Task TestBlobSASAsync(ICloudBlob testBlob, SharedAccessBlobPermissions permissions) - { - await UploadTextAsync(testBlob, "blob", Encoding.UTF8); - - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - - string sasToken = testBlob.GetSharedAccessSignature(policy); - await SASTests.TestAccessAsync(sasToken, permissions, null, testBlob); - } - - [TestMethod] - [Description("Test updateSASToken")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerUpdateSASTokenAsync() - { - // Create a policy with read/write acces and get SAS. - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - await TestAccessAsync(sasToken, SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write, this.testContainer, testBlockBlob); - - StorageCredentials creds = new StorageCredentials(sasToken); - - // Change the policy to only read and update SAS. - SharedAccessBlobPolicy policy2 = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessBlobPermissions.Read - }; - string sasToken2 = this.testContainer.GetSharedAccessSignature(policy2); - creds.UpdateSASToken(sasToken2); - - // Extra check to make sure that we have actually uopdated the SAS token. - CloudBlobContainer container = new CloudBlobContainer(this.testContainer.Uri, creds); - CloudBlockBlob blob = container.GetBlockBlobReference("blockblob2"); - OperationContext operationContext = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await UploadTextAsync(blob, "blob", Encoding.UTF8, null, null, operationContext), - operationContext, - "Writing to a blob while SAS does not allow for writing", - HttpStatusCode.NotFound); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - await testPageBlob.CreateAsync(0); - await TestAccessAsync(sasToken2, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerSASCombinationsAsync() - { - for (int i = 1; i < 16; i++) - { - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = permissions, - }; - string sasToken = this.testContainer.GetSharedAccessSignature(policy); - - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob" + i); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - await SASTests.TestAccessAsync(sasToken, permissions, this.testContainer, testBlockBlob); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob" + i); - await UploadTextAsync(testPageBlob, "blob", Encoding.UTF8); - await SASTests.TestAccessAsync(sasToken, permissions, this.testContainer, testPageBlob); - } - } - - [TestMethod] - [Description("Test access on a public container")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlobContainerPublicAccessAsync() - { - CloudBlockBlob testBlockBlob = this.testContainer.GetBlockBlobReference("blockblob"); - await UploadTextAsync(testBlockBlob, "blob", Encoding.UTF8); - - CloudPageBlob testPageBlob = this.testContainer.GetPageBlobReference("pageblob"); - await UploadTextAsync(testPageBlob, "blob", Encoding.UTF8); - - BlobContainerPermissions permissions = new BlobContainerPermissions(); - - permissions.PublicAccess = BlobContainerPublicAccessType.Container; - await this.testContainer.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.List | SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - - permissions.PublicAccess = BlobContainerPublicAccessType.Blob; - await this.testContainer.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.Read, this.testContainer, testBlockBlob); - await SASTests.TestAccessAsync(null, SharedAccessBlobPermissions.Read, this.testContainer, testPageBlob); - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudBlockBlobSASCombinationsAsync() - { - for (int i = 1; i < 8; i++) - { - CloudBlockBlob testBlob = this.testContainer.GetBlockBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - await SASTests.TestBlobSASAsync(testBlob, permissions); - } - } - - [TestMethod] - [Description("Test all combinations of blob permissions against a block blob")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudPageBlobSASCombinationsAsync() - { - for (int i = 1; i < 8; i++) - { - CloudPageBlob testBlob = this.testContainer.GetPageBlobReference("blob" + i); - SharedAccessBlobPermissions permissions = (SharedAccessBlobPermissions)i; - await SASTests.TestBlobSASAsync(testBlob, permissions); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/DescriptionAttribute.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/DescriptionAttribute.cs deleted file mode 100644 index f986032deeb12..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/DescriptionAttribute.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Microsoft.WindowsAzure.Storage -{ - using System; - - public sealed class DescriptionAttribute : Attribute - { - public DescriptionAttribute(string description) - { - this.Description = description; - } - - public string Description { get; internal set; } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/LocalizedStrings.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/LocalizedStrings.cs deleted file mode 100644 index 0faa7bd9f66ce..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/LocalizedStrings.cs +++ /dev/null @@ -1,31 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.WindowsAzure.Storage.Resources; - -namespace Microsoft.WindowsAzure.Storage -{ - /// - /// Provides access to string resources. - /// - public class LocalizedStrings - { - private static AppResources _localizedResources = new AppResources(); - - public AppResources LocalizedResources { get { return _localizedResources; } } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml b/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml deleted file mode 100644 index 5d66129a90800..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml.cs deleted file mode 100644 index b3d4b351ee17e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/MainPage.xaml.cs +++ /dev/null @@ -1,36 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.Phone.Controls; -using Microsoft.VisualStudio.TestPlatform.Core; -using Microsoft.VisualStudio.TestPlatform.TestExecutor; -using System.Threading; -using vstest_executionengine_platformbridge; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class MainPage : PhoneApplicationPage - { - public MainPage() - { - InitializeComponent(); - - var wrapper = new TestExecutorServiceWrapper(); - new Thread(new ServiceMain((param0, param1) => wrapper.SendMessage((ContractName)param0, param1)).Run).Start(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AppManifest.xml b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AppManifest.xml deleted file mode 100644 index 6712a11783932..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AppManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AssemblyInfo.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AssemblyInfo.cs deleted file mode 100644 index a5c27421e4794..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Resources; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.WindowsAzure.StorageWP.Test.dll")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Windows Azure Storage")] -[assembly: AssemblyCopyright("Copyright © 2012 Microsoft Corp.")] -[assembly: AssemblyTrademark("Microsoft ® is a registered trademark of Microsoft Corporation.")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("e0010776-cac8-4ec7-8d21-0d0896c32afc")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("2.1.0.4")] -[assembly: AssemblyFileVersion("2.1.0.4")] -[assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/WMAppManifest.xml b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/WMAppManifest.xml deleted file mode 100644 index c57eb8cc58f45..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Properties/WMAppManifest.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Assets\ApplicationIcon.png - - - - - - - - - - - - - - Assets\Tiles\FlipCycleTileSmall.png - 0 - Assets\Tiles\FlipCycleTileMedium.png - Windows Azure Storage Library Test - - - - - - - - - - - vstest_executionengine_platformbridge.dll - - - - - - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueClientTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueClientTest.cs deleted file mode 100644 index f089500b849bb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueClientTest.cs +++ /dev/null @@ -1,187 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueClientTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("A test checks basic function of CloudQueueClient.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudQueueClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.QueueServiceEndpoint); - CloudQueueClient queueClient = new CloudQueueClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(queueClient.BaseUri.ToString().StartsWith(TestBase.TargetTenantConfig.QueueServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, queueClient.Credentials); - Assert.AreEqual(AuthenticationScheme.SharedKey, queueClient.AuthenticationScheme); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientListQueuesBasicAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = GenerateNewQueueName(); - List queueNames = new List(); - int count = 30; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueResultSegment emptyResults = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.All, null, null, null, null); - Assert.AreEqual(0, emptyResults.Results.Count()); - - foreach (string name in queueNames) - { - await client.GetQueueReference(name).CreateAsync(); - } - - QueueResultSegment results = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.All, null, null, null, null); - - foreach (CloudQueue queue in results.Results) - { - if (queueNames.Remove(queue.Name)) - { - await queue.DeleteAsync(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(count, results.Results.Count()); - } - - [TestMethod] - [Description("Test Create Queue with Shared Key Lite")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientCreateQueueSharedKeyLiteAsync() - { - CloudQueueClient queueClient = GenerateCloudQueueClient(); - queueClient.AuthenticationScheme = AuthenticationScheme.SharedKeyLite; - - string queueName = GenerateNewQueueName(); - CloudQueue queue = queueClient.GetQueueReference(queueName); - await queue.CreateAsync(); - - bool exists = await queue.ExistsAsync(); - Assert.IsTrue(exists); - } - - [TestMethod] - [Description("List queues")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClientListQueuesSegmentedAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string prefix = "rtqueuetest" + Guid.NewGuid().ToString("N"); - List queueNames = new List(); - int count = 3; - for (int i = 0; i < count; i++) - { - queueNames.Add(prefix + i); - } - - QueueContinuationToken token = null; - List results = new List(); - - do - { - QueueResultSegment segment = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, null, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(0, results.Count); - - foreach (string name in queueNames) - { - await client.GetQueueReference(name).CreateAsync(); - } - - do - { - QueueResultSegment segment = await client.ListQueuesSegmentedAsync(prefix, QueueListingDetails.None, 10, token, null, null); - token = segment.ContinuationToken; - results.AddRange(segment.Results); - } - while (token != null); - - Assert.AreEqual(results.Count, queueNames.Count); - - foreach (CloudQueue queue in results) - { - if (queueNames.Remove(queue.Name)) - { - await queue.DeleteAsync(); - } - else - { - Assert.Fail(); - } - } - - Assert.AreEqual(0, queueNames.Count); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueMessageTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueMessageTest.cs deleted file mode 100644 index fcd458193fa6d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueMessageTest.cs +++ /dev/null @@ -1,261 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueMessageTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Test CloudQueueMessage constructor.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateIfNotExistsAsync(); - - CloudQueueMessage message = new CloudQueueMessage(Guid.NewGuid().ToString()); - await queue.AddMessageAsync(message); - - CloudQueueMessage retrMessage = await queue.GetMessageAsync(); - string messageId = retrMessage.Id; - string popReceipt = retrMessage.PopReceipt; - - // Recreate the message using the messageId and popReceipt. - CloudQueueMessage newMessage = new CloudQueueMessage(messageId, popReceipt); - Assert.AreEqual(messageId, newMessage.Id); - Assert.AreEqual(popReceipt, newMessage.PopReceipt); - - await queue.UpdateMessageAsync(newMessage, TimeSpan.FromSeconds(30), MessageUpdateFields.Visibility); - CloudQueueMessage retrMessage2 = await queue.GetMessageAsync(); - Assert.AreEqual(null, retrMessage2); - } - finally - { - queue.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test add/delete message")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueMessageAddDelete() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - - await queue.AddMessageAsync(new CloudQueueMessage("abcde")); - - CloudQueueMessage receivedMessage1 = await queue.GetMessageAsync(); - - await queue.DeleteMessageAsync(receivedMessage1.Id, receivedMessage1.PopReceipt); - - CloudQueueMessage receivedMessage2 = await queue.GetMessageAsync(); - Assert.IsNull(receivedMessage2); - } - - [TestMethod] - [Description("Test whether get message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - CloudQueueMessage emptyMessage = await queue.GetMessageAsync(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.GetMessageAsync(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Test whether get messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetMessagesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - int messageCount = 30; - - List emptyMessages = (await queue.GetMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = (await queue.GetMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Test whether peek message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueuePeekMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - CloudQueueMessage emptyMessage = await queue.PeekMessageAsync(); - Assert.IsNull(emptyMessage); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.PeekMessageAsync(); - - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Test whether peek messages.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueuePeekMessagesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - int messageCount = 30; - - List emptyMessages = (await queue.PeekMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(0, emptyMessages.Count); - - List messageContentList = new List(); - for (int i = 0; i < messageCount; i++) - { - string messageContent = i.ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - messageContentList.Add(messageContent); - } - - List receivedMessages = (await queue.PeekMessagesAsync(messageCount)).ToList(); - Assert.AreEqual(messageCount, receivedMessages.Count); - - for (int i = 0; i < messageCount; i++) - { - Assert.IsTrue(messageContentList.Contains(receivedMessages[i].AsString)); - } - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Test whether clear message.")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueClearMessageAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - string name = GenerateNewQueueName(); - CloudQueue queue = client.GetQueueReference(name); - await queue.CreateAsync(); - - string msgContent = Guid.NewGuid().ToString("N"); - CloudQueueMessage message = new CloudQueueMessage(msgContent); - await queue.AddMessageAsync(message); - CloudQueueMessage receivedMessage1 = await queue.PeekMessageAsync(); - Assert.IsTrue(receivedMessage1.AsString == message.AsString); - await queue.ClearAsync(); - Assert.IsNull(await queue.PeekMessageAsync()); - await queue.DeleteAsync(); - } - } -} \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueTest.cs deleted file mode 100644 index c1e6589d0972e..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/CloudQueueTest.cs +++ /dev/null @@ -1,343 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Auth; -using Microsoft.WindowsAzure.Storage.Queue.Protocol; -using System; -using System.Globalization; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class CloudQueueTest : QueueTestBase - { - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - [TestMethod] - [Description("Create and delete a queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateAndDeleteAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - await queue.CreateAsync(); - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Try to create a queue after it is created")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueCreateIfNotExistsAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - try - { - Assert.IsTrue(await queue.CreateIfNotExistsAsync()); - Assert.IsFalse(await queue.CreateIfNotExistsAsync()); - } - finally - { - queue.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Try to delete a non-existing queue")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueDeleteIfExistsAsync() - { - string name = GenerateNewQueueName(); - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(name); - - Assert.IsFalse(await queue.DeleteIfExistsAsync()); - await queue.CreateAsync(); - Assert.IsTrue(await queue.DeleteIfExistsAsync()); - Assert.IsFalse(await queue.DeleteIfExistsAsync()); - } - - [TestMethod] - [Description("Set/get queue permissions")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueGetSetPermissionsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - QueuePermissions emptyPermission = await queue.GetPermissionsAsync(); - Assert.AreEqual(emptyPermission.SharedAccessPolicies.Count, 0); - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - await queue.FetchAttributesAsync(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - QueuePermissions permissionsToRetrieve = await queueToRetrieve.GetPermissionsAsync(); - - Assert.AreEqual(permissions.SharedAccessPolicies.Count, permissionsToRetrieve.SharedAccessPolicies.Count); - //Assert.AreEqual(start, permissionsToRetrieve.SharedAccessPolicies[id].SharedAccessStartTime.Value.UtcDateTime); - //Assert.AreEqual(expiry, permissionsToRetrieve.SharedAccessPolicies[id].SharedAccessExpiryTime.Value.UtcDateTime); - Assert.AreEqual(permissions.SharedAccessPolicies[id].Permissions, permissionsToRetrieve.SharedAccessPolicies[id].Permissions); - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Set/get a queue with metadata")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueSetGetMetadataAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - await queue.CreateAsync(); - - CloudQueue queueToRetrieve = client.GetQueueReference(queue.Name); - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - queue.Metadata.Add("key1", "value1"); - await queue.SetMetadataAsync(); - - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(1, queueToRetrieve.Metadata.Count); - Assert.AreEqual("value1", queueToRetrieve.Metadata["key1"]); - - queue.Metadata.Clear(); - await queue.SetMetadataAsync(); - - await queueToRetrieve.FetchAttributesAsync(); - Assert.AreEqual(0, queueToRetrieve.Metadata.Count); - - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Test queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task QueueSASTestAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage1 = await sasQueueFromId.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage2 = await sasQueueFromPolicy.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - await queue.DeleteAsync(); - } - - [TestMethod] - [Description("Update queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task UpdateQueueSASTestAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - SharedAccessQueuePolicy policy = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages, - }; - string id = Guid.NewGuid().ToString(); - string sasToken = queue.GetSharedAccessSignature(policy, null); - - StorageCredentials sasCreds = new StorageCredentials(sasToken); - CloudQueue sasQueue = new CloudQueue(queue.Uri, sasCreds); - OperationContext context = new OperationContext(); - - await TestHelper.ExpectedExceptionAsync( - async () => await sasQueue.PeekMessageAsync(null, context), - context, - "Peek when Sas does not allow Read access on the queue", - HttpStatusCode.NotFound); - - await sasQueue.AddMessageAsync(message); - - SharedAccessQueuePolicy policy2 = new SharedAccessQueuePolicy() - { - SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5), - SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30), - Permissions = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read, - }; - - string sasToken2 = queue.GetSharedAccessSignature(policy2, null); - sasCreds.UpdateSASToken(sasToken2); - sasQueue = new CloudQueue(queue.Uri, sasCreds); - - await sasQueue.PeekMessageAsync(); - } - finally - { - queue.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test queue sas")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task QueueRegionalSASTestAsync() - { - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT"); - - CloudQueueClient client = GenerateCloudQueueClient(); - CloudQueue queue = client.GetQueueReference(GenerateNewQueueName()); - - try - { - await queue.CreateAsync(); - string messageContent = Guid.NewGuid().ToString(); - CloudQueueMessage message = new CloudQueueMessage(messageContent); - await queue.AddMessageAsync(message); - - // Prepare SAS authentication with full permissions - string id = Guid.NewGuid().ToString(); - DateTime start = DateTime.UtcNow; - DateTime expiry = start.AddMinutes(30); - QueuePermissions permissions = new QueuePermissions(); - SharedAccessQueuePermissions queuePerm = SharedAccessQueuePermissions.Add | SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Read | SharedAccessQueuePermissions.Update; - permissions.SharedAccessPolicies.Add(id, new SharedAccessQueuePolicy() - { - SharedAccessStartTime = start, - SharedAccessExpiryTime = expiry, - Permissions = queuePerm - }); - - await queue.SetPermissionsAsync(permissions); - await Task.Delay(30 * 1000); - - string sasTokenFromId = queue.GetSharedAccessSignature(null, id); - StorageCredentials sasCredsFromId = new StorageCredentials(sasTokenFromId); - CloudQueue sasQueueFromId = new CloudQueue(queue.Uri, sasCredsFromId); - CloudQueueMessage receivedMessage1 = await sasQueueFromId.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage1.AsString); - - string sasTokenFromPolicy = queue.GetSharedAccessSignature(permissions.SharedAccessPolicies[id], null); - StorageCredentials sasCredsFromPolicy = new StorageCredentials(sasTokenFromPolicy); - CloudQueue sasQueueFromPolicy = new CloudQueue(queue.Uri, sasCredsFromPolicy); - CloudQueueMessage receivedMessage2 = await sasQueueFromPolicy.PeekMessageAsync(); - Assert.AreEqual(messageContent, receivedMessage2.AsString); - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - queue.DeleteAsync().Wait(); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/QueueAnalyticsUnitTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/QueueAnalyticsUnitTests.cs deleted file mode 100644 index db19d6c76770a..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Queue/QueueAnalyticsUnitTests.cs +++ /dev/null @@ -1,359 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Queue -{ - [TestClass] - public class QueueAnalyticsUnitTests : TestBase - { - #region Locals + Ctors - public QueueAnalyticsUnitTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudQueueClient client = GenerateCloudQueueClient(); - startProperties = await client.GetServicePropertiesAsync(); - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - CloudQueueClient client = GenerateCloudQueueClient(); - await client.SetServicePropertiesAsync(startProperties); - } - - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public void MyTestInitialize() - { - if (TestBase.QueueBufferManager != null) - { - TestBase.QueueBufferManager.OutstandingBufferCount = 0; - } - } - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public void MyTestCleanup() - { - if (TestBase.QueueBufferManager != null) - { - Assert.AreEqual(0, TestBase.QueueBufferManager.OutstandingBufferCount); - } - } - - #endregion - - #region Analytics RoundTrip - - [TestMethod] - [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsRoundTripAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsDisableAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsDefaultServiceVersionThrowsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - await client.SetServicePropertiesAsync(props, null, ctx); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.HttpStatusMessage, "XML specified is not syntactically valid."); - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - return; - } - - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsLoggingOperationsAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsMetricsLevelAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Queue)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudQueueTestAnalyticsRetentionPoliciesAsync() - { - CloudQueueClient client = GenerateCloudQueueClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.Designer.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.Designer.cs deleted file mode 100644 index c24b0c1574e00..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.Designer.cs +++ /dev/null @@ -1,108 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18033 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.WindowsAzure.Storage.Resources { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class AppResources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal AppResources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.WindowsAzure.Storage.Resources.AppResources", typeof(AppResources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to add. - /// - public static string AppBarButtonText { - get { - return ResourceManager.GetString("AppBarButtonText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Menu Item. - /// - public static string AppBarMenuItemText { - get { - return ResourceManager.GetString("AppBarMenuItemText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to MY APPLICATION. - /// - public static string ApplicationTitle { - get { - return ResourceManager.GetString("ApplicationTitle", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to LeftToRight. - /// - public static string ResourceFlowDirection { - get { - return ResourceManager.GetString("ResourceFlowDirection", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to en-US. - /// - public static string ResourceLanguage { - get { - return ResourceManager.GetString("ResourceLanguage", resourceCulture); - } - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.resx b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.resx deleted file mode 100644 index 529a19431a71b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Resources/AppResources.resx +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - LeftToRight - Controls the FlowDirection for all elements in the RootFrame. Set to the traditional direction of this resource file's language - - - en-US - Controls the Language and ensures that the font for all elements in the RootFrame aligns with the app's language. Set to the language code of this resource file's language. - - - MY APPLICATION - - - add - - - Menu Item - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/SampleTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/SampleTest.cs deleted file mode 100644 index 02557e85e653d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/SampleTest.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Blob; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage -{ - [TestClass] - public class SampleTest : BlobTestBase - { - private CloudBlobContainer testContainer; - - [TestInitialize] - public async Task TestInitialize() - { - this.testContainer = GetRandomContainerReference(); - await this.testContainer.CreateAsync(); - } - - [TestMethod] - public async Task SampleFetchTest() - { - await this.testContainer.FetchAttributesAsync(); - } - - [TestCleanup] - public async Task TestCleanup() - { - await this.testContainer.DeleteIfExistsAsync(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableCRUDUnitTaskTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableCRUDUnitTaskTests.cs deleted file mode 100644 index 414c6d114a9c5..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableCRUDUnitTaskTests.cs +++ /dev/null @@ -1,295 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - /// - /// Summary description for CloudTableCRUDUnitTaskTests - /// - [TestClass] - public class CloudTableCRUDUnitTaskTests : TableTestBase - { - #region Locals + Ctors - public CloudTableCRUDUnitTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - // public static void MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - // public static void MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - //[TestInitialize()] - // public async void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - //[TestCleanup()] - // public async void MyTestCleanup() { } - // - #endregion - - #region Table Create - - [TestMethod] - [Description("Test Table Create - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table Create When Table Already Exists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateAlreadyExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - - // This should throw with no retries - await tableRef.CreateAsync(null, ctx); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.ExtendedErrorInformation.ErrorCode, "TableAlreadyExists"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - - #region Table CreateIfNotExists - - [TestMethod] - [Description("Test Table CreateIfNotExists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableCreateIfNotExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - Assert.IsTrue(await tableRef.CreateIfNotExistsAsync()); - Assert.IsTrue(await tableRef.ExistsAsync()); - Assert.IsFalse(await tableRef.CreateIfNotExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - - #region Table Delete - - [TestMethod] - [Description("Test Table Delete - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - await tableRef.DeleteAsync(); - Assert.IsFalse(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("Test Table Delete When Table Does Not Exist - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteWhenNotExistAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - OperationContext ctx = new OperationContext(); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - - // This should throw with no retries - await tableRef.DeleteAsync(null, ctx); - Assert.Fail(); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.HttpStatusCode, 404); - Assert.AreEqual(ctx.LastResult.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); - TestHelper.AssertNAttempts(ctx, 1); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - - #region Table DeleteIfExists - - [TestMethod] - [Description("Test Table DeleteIfExists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableDeleteIfExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - Assert.IsFalse(await tableRef.DeleteIfExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - Assert.IsTrue(await tableRef.DeleteIfExistsAsync()); - Assert.IsFalse(await tableRef.DeleteIfExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - - #region Table Exists - - [TestMethod] - [Description("Test Table Exists - Async")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableExistsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string tableName = GenerateRandomTableName(); - CloudTable tableRef = tableClient.GetTableReference(tableName); - - try - { - Assert.IsFalse(await tableRef.ExistsAsync()); - await tableRef.CreateAsync(); - Assert.IsTrue(await tableRef.ExistsAsync()); - await tableRef.DeleteAsync(); - Assert.IsFalse(await tableRef.ExistsAsync()); - } - finally - { - tableRef.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableClientTaskTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableClientTaskTest.cs deleted file mode 100644 index d1dfbe10f3066..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/CloudTableClientTaskTest.cs +++ /dev/null @@ -1,211 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class CloudTableClientTaskTest : TableTestBase - { - #region Locals + Ctors - public CloudTableClientTaskTest() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static List createdTables = new List(); - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // 20 random tables - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(GenerateRandomTableName()); - await tableRef.CreateIfNotExistsAsync(); - createdTables.Add(tableRef); - } - - prefixTablesPrefix = "prefixtable" + GenerateRandomTableName(); - // 20 tables with known prefix - for (int m = 0; m < 20; m++) - { - CloudTable tableRef = tableClient.GetTableReference(prefixTablesPrefix + m.ToString()); - await tableRef.CreateIfNotExistsAsync(); - createdTables.Add(tableRef); - } - } - - private static string prefixTablesPrefix = null; - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - foreach (CloudTable t in createdTables) - { - try - { - await t.DeleteIfExistsAsync(); - } - catch (Exception) - { - } - } - } - - // - // Use TestInitialize to run code before running each test - // [TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - // [TestCleanup()] - // public void MyTestCleanup() { } - // - #endregion - - #region Ctor Tests - [TestMethod] - [Description("A test checks constructor of CloudTableClient.")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void CloudTableClientConstructor() - { - Uri baseAddressUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint); - CloudTableClient TableClient = new CloudTableClient(baseAddressUri, TestBase.StorageCredentials); - Assert.IsTrue(TableClient.BaseUri.ToString().StartsWith(TestBase.TargetTenantConfig.TableServiceEndpoint)); - Assert.AreEqual(TestBase.StorageCredentials, TableClient.Credentials); - } - #endregion - - #region List Tables Segmented - - [TestMethod] - [Description("Test List Tables Segmented Basic Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedBasicAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - do - { - segment = await tableClient.ListTablesSegmentedAsync(segment != null ? segment.ContinuationToken : null, CancellationToken.None); - totalResults.AddRange(segment); - } - while (segment.ContinuationToken != null); - - // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - } - - [TestMethod] - [Description("Test List Tables Segmented MaxResults Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedMaxResultsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = await tableClient.ListTablesSegmentedAsync(string.Empty, 10, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); - Assert.IsTrue(segCount >= totalResults.Count / 10); - } - - [TestMethod] - [Description("Test List Tables Segmented With Prefix Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task ListTablesSegmentedWithPrefixAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - TableResultSegment segment = null; - List totalResults = new List(); - - int segCount = 0; - do - { - segment = await tableClient.ListTablesSegmentedAsync(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null); - totalResults.AddRange(segment); - segCount++; - } - while (segment.ContinuationToken != null); - - Assert.AreEqual(totalResults.Count, 20); - foreach (CloudTable tbl in totalResults) - { - Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); - } - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableAnalyticsUnitTaskTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableAnalyticsUnitTaskTests.cs deleted file mode 100644 index ef11a2e52eeca..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableAnalyticsUnitTaskTests.cs +++ /dev/null @@ -1,346 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Shared.Protocol; -using System; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableAnalyticsUnitTaskTests : TestBase - { - #region Locals + Ctors - public TableAnalyticsUnitTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - private static ServiceProperties startProperties = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudTableClient client = GenerateCloudTableClient(); - startProperties = await client.GetServicePropertiesAsync(); - } - - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - CloudTableClient client = GenerateCloudTableClient(); - await client.SetServicePropertiesAsync(startProperties); - } - // - // Use TestInitialize to run code before running each test - //[TestInitialize()] - // public void MyTestInitialize() { } - // - // Use TestCleanup to run code after each test has run - //[TestCleanup()] - // public void MyTestCleanup() { } - // - #endregion - - #region Analytics RoundTrip - - [TestMethod] - [Description("Test Analytics Round Trip Async")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsRoundTripAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.Read | LoggingOperations.Write; - props.Logging.RetentionDays = 5; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.Service; - props.Metrics.RetentionDays = 6; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - #endregion - - #region Analytics Permutations - - [TestMethod] - [Description("Test Analytics Disable Service Properties")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsDisableAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = new ServiceProperties(); - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Default Service VersionThrows")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsDefaultServiceVersionThrowsAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - OperationContext ctx = new OperationContext(); - - ServiceProperties props = new ServiceProperties(); - props.DefaultServiceVersion = "2009-09-19"; - - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.Version = "1.0"; - - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.Version = "1.0"; - - try - { - await client.SetServicePropertiesAsync(props, null, ctx); - } - catch (Exception) - { - Assert.AreEqual(ctx.LastResult.HttpStatusMessage, "XML specified is not syntactically valid."); - Assert.AreEqual(ctx.LastResult.HttpStatusCode, (int)HttpStatusCode.BadRequest); - TestHelper.AssertNAttempts(ctx, 1); - return; - } - - Assert.Fail("Should not be able to set default Service Version for non Blob Client"); - } - - [TestMethod] - [Description("Test Analytics Logging Operations")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsLoggingOperationsAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Logging.LoggingOperations = LoggingOperations.None; - props.Logging.RetentionDays = null; - props.Logging.Version = "1.0"; - - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // None - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Metrics Level")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsMetricsLevelAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // None - props.Metrics.MetricsLevel = MetricsLevel.None; - props.Metrics.RetentionDays = null; - props.Metrics.Version = "1.0"; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Service - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // ServiceAndAPI - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - - [TestMethod] - [Description("Test Analytics Retention Policies")] - [TestCategory(ComponentCategory.Blob)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task CloudTableTestAnalyticsRetentionPoliciesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - ServiceProperties props = await client.GetServicePropertiesAsync(); - - // Set retention policy null with metrics disabled. - props.Metrics.RetentionDays = null; - props.Metrics.MetricsLevel = MetricsLevel.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics disabled. - props.Metrics.RetentionDays = 1; - props.Metrics.MetricsLevel = MetricsLevel.Service; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with metrics enabled. - props.Metrics.MetricsLevel = MetricsLevel.ServiceAndApi; - props.Metrics.RetentionDays = 2; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging disabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging disabled. - props.Logging.RetentionDays = 3; - props.Logging.LoggingOperations = LoggingOperations.None; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy null with logging enabled. - props.Logging.RetentionDays = null; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - - // Set retention policy not null with logging enabled. - props.Logging.RetentionDays = 4; - props.Logging.LoggingOperations = LoggingOperations.All; - await client.SetServicePropertiesAsync(props); - - // Wait for analytics server to update - await Task.Delay(60 * 1000); - AssertServicePropertiesAreEqual(props, await client.GetServicePropertiesAsync()); - } - #endregion - - #region Test Helpers - - private void AssertServicePropertiesAreEqual(ServiceProperties propsA, ServiceProperties propsB) - { - Assert.AreEqual(propsA.Logging.LoggingOperations, propsB.Logging.LoggingOperations); - Assert.AreEqual(propsA.Logging.RetentionDays, propsB.Logging.RetentionDays); - Assert.AreEqual(propsA.Logging.Version, propsB.Logging.Version); - - Assert.AreEqual(propsA.Metrics.MetricsLevel, propsB.Metrics.MetricsLevel); - Assert.AreEqual(propsA.Metrics.RetentionDays, propsB.Metrics.RetentionDays); - Assert.AreEqual(propsA.Metrics.Version, propsB.Metrics.Version); - - Assert.AreEqual(propsA.DefaultServiceVersion, propsB.DefaultServiceVersion); - } - - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableBatchOperationTaskTest.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableBatchOperationTaskTest.cs deleted file mode 100644 index 0e48887d1ea0c..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableBatchOperationTaskTest.cs +++ /dev/null @@ -1,1358 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableBatchOperationTaskTest : TableTestBase - { - #region Locals + Ctors - public TableBatchOperationTaskTest() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public async Task MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public async Task MyTestCleanup() - { - await currentTable.DeleteIfExistsAsync(); - } - - #endregion - - #region Insert - - [TestMethod] - [Description("A test to check batch insert functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertAsync() - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 3; m++) - { - AddInsertToBatch(pk, batch); - } - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Add delete - batch.Delete(ent); - - IList results = await currentTable.ExecuteBatchAsync(batch); - - Assert.AreEqual(results.Count, 4); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - // delete - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - [TestMethod] - [Description("A test to check batch insert functionality when entity already exists")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - #endregion - - #region Insert Or Merge - - [TestMethod] - [Description("TableBatch Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMergeAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrMerge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch2); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Insert Or Replace - - [TestMethod] - [Description("TableOperation Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrReplaceAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch2 = new TableBatchOperation(); - batch2.InsertOrReplace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch2); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Delete - - [TestMethod] - [Description("A test to check batch delete functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity ent = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - TableBatchOperation batch = new TableBatchOperation(); - - // Add delete - batch.Delete(ent); - - // success - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NoContent); - - // fail - not found - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - [TestMethod] - [Description("A test to check batch delete failure")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchDeleteFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - ITableEntity ent = GenerateRandomEnitity("foo"); - - // add entity - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // update entity - TableResult res = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEnt = res.Result as DynamicTableEntity; - retrievedEnt.Properties.Add("prop", new EntityProperty("var")); - await currentTable.ExecuteAsync(TableOperation.Replace(retrievedEnt)); - - // Attempt to delete with stale etag - TableBatchOperation batch = new TableBatchOperation(); - batch.Delete(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - #endregion - - #region Merge - - [TestMethod] - [Description("TableBatch Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchMergeAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Merge Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchMergeFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region Replace - - [TestMethod] - [Description("TableBatch Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchReplaceAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableBatch Replace Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchReplaceFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - #endregion - - #region Batch With All Supported Operations - - [TestMethod] - [Description("A test to check batch with all supported operations")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchAllSupportedOperationsAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - // insert - batch.Insert(GenerateRandomEnitity(pk)); - - // delete - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Delete(entity); - } - - // replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Replace(entity); - } - - // insert or replace - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.InsertOrReplace(entity); - } - - // merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.Merge(entity); - } - - // insert or merge - { - DynamicTableEntity entity = GenerateRandomEnitity(pk); - await currentTable.ExecuteAsync(TableOperation.Insert(entity)); - batch.InsertOrMerge(entity); - } - - IList results = await currentTable.ExecuteBatchAsync(batch); - - Assert.AreEqual(results.Count, 6); - - IEnumerator enumerator = results.GetEnumerator(); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.Created); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - enumerator.MoveNext(); - Assert.AreEqual(enumerator.Current.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - - #endregion - - #region Retrieve - - [TestMethod] - [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(pk); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey); - - // not found - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = results.First().Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt.Properties["String"], retrievedEntity.Properties["String"]); - Assert.AreEqual(sendEnt.Properties["Int64"], retrievedEntity.Properties["Int64"]); - Assert.AreEqual(sendEnt.Properties["Int64N"], retrievedEntity.Properties["Int64N"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitive"], retrievedEntity.Properties["LongPrimitive"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitiveN"], retrievedEntity.Properties["LongPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Int32"], retrievedEntity.Properties["Int32"]); - Assert.AreEqual(sendEnt.Properties["Int32N"], retrievedEntity.Properties["Int32N"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitive"], retrievedEntity.Properties["IntegerPrimitive"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitiveN"], retrievedEntity.Properties["IntegerPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Guid"], retrievedEntity.Properties["Guid"]); - Assert.AreEqual(sendEnt.Properties["GuidN"], retrievedEntity.Properties["GuidN"]); - Assert.AreEqual(sendEnt.Properties["Double"], retrievedEntity.Properties["Double"]); - Assert.AreEqual(sendEnt.Properties["DoubleN"], retrievedEntity.Properties["DoubleN"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitive"], retrievedEntity.Properties["DoublePrimitive"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitiveN"], retrievedEntity.Properties["DoublePrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["BinaryPrimitive"], retrievedEntity.Properties["BinaryPrimitive"]); - Assert.AreEqual(sendEnt.Properties["Binary"], retrievedEntity.Properties["Binary"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"], retrievedEntity.Properties["BoolPrimitive"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"], retrievedEntity.Properties["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Bool"], retrievedEntity.Properties["Bool"]); - Assert.AreEqual(sendEnt.Properties["BoolN"], retrievedEntity.Properties["BoolN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"], retrievedEntity.Properties["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffset"], retrievedEntity.Properties["DateTimeOffset"]); - Assert.AreEqual(sendEnt.Properties["DateTime"], retrievedEntity.Properties["DateTime"]); - Assert.AreEqual(sendEnt.Properties["DateTimeN"], retrievedEntity.Properties["DateTimeN"]); - } - - [TestMethod] - [Description("A test to check batch retrieve with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveWithResolverAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Add insert - DynamicTableEntity sendEnt = GenerateRandomEnitity(Guid.NewGuid().ToString()); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver = (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver); - - // not found - IList results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(results.First().Result); - Assert.IsNull(results.First().Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - results = await currentTable.ExecuteBatchAsync(batch); - Assert.AreEqual(results.Count, 1); - Assert.AreEqual(results.First().HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)results.First().Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt.Properties["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - #endregion - - #region Empty Keys Test - - [TestMethod] - [Description("TableBatchOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOperationsWithEmptyKeysAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - TableBatchOperation batch = new TableBatchOperation(); - batch.Insert(ent); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity - TableBatchOperation retrieveBatch = new TableBatchOperation(); - retrieveBatch.Retrieve(ent.PartitionKey, ent.RowKey); - TableResult result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - batch = new TableBatchOperation(); - batch.InsertOrMerge(insertOrMergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - batch = new TableBatchOperation(); - batch.InsertOrReplace(insertOrReplaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - batch = new TableBatchOperation(); - batch.Merge(mergeEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - batch = new TableBatchOperation(); - batch.Replace(replaceEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity & Verify Contents - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - batch = new TableBatchOperation(); - batch.Delete(retrievedEntity); - await currentTable.ExecuteBatchAsync(batch); - - // Retrieve Entity - result = (await currentTable.ExecuteBatchAsync(retrieveBatch)).First(); - Assert.IsNull(result.Result); - } - - #endregion - - #region Bulk insert - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert1Async() - { - await InsertAndDeleteBatchWithNEntities(1); - } - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert10Async() - { - await InsertAndDeleteBatchWithNEntities(10); - } - - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert99Async() - { - await InsertAndDeleteBatchWithNEntities(99); - } - - [TestMethod] - [Description("A test to peform batch insert and delete with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsert100Async() - { - await InsertAndDeleteBatchWithNEntities(100); - } - - private async Task InsertAndDeleteBatchWithNEntities(int n) - { - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < n; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - IList results = await currentTable.ExecuteBatchAsync(batch); - - TableBatchOperation delBatch = new TableBatchOperation(); - - foreach (TableResult res in results) - { - delBatch.Delete((ITableEntity)res.Result); - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.Created); - } - - IList delResults = await currentTable.ExecuteBatchAsync(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Bulk Upsert - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge1Async() - { - await InsertOrMergeBatchWithNEntities(1); - } - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge10Async() - { - await InsertOrMergeBatchWithNEntities(10); - } - - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge99Async() - { - await InsertOrMergeBatchWithNEntities(99); - } - - [TestMethod] - [Description("A test to peform batch InsertOrMerge with batch size of 1")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchInsertOrMerge100Async() - { - await InsertOrMergeBatchWithNEntities(100); - } - - private async Task InsertOrMergeBatchWithNEntities(int n) - { - string pk = Guid.NewGuid().ToString(); - - TableBatchOperation insertBatch = new TableBatchOperation(); - TableBatchOperation mergeBatch = new TableBatchOperation(); - TableBatchOperation delBatch = new TableBatchOperation(); - - for (int m = 0; m < n; m++) - { - insertBatch.InsertOrMerge(GenerateRandomEnitity(pk)); - } - - IList results = await currentTable.ExecuteBatchAsync(insertBatch); - foreach (TableResult res in results) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // update entity and add to merge batch - DynamicTableEntity ent = res.Result as DynamicTableEntity; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - mergeBatch.InsertOrMerge(ent); - - } - - // execute insertOrMerge batch, this time entities exist - IList mergeResults = await currentTable.ExecuteBatchAsync(mergeBatch); - - foreach (TableResult res in mergeResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - - // Add to delete batch - delBatch.Delete((ITableEntity)res.Result); - } - - IList delResults = await currentTable.ExecuteBatchAsync(delBatch); - foreach (TableResult res in delResults) - { - Assert.AreEqual(res.HttpStatusCode, (int)HttpStatusCode.NoContent); - } - } - #endregion - - #region Boundary Conditions - - [TestMethod] - [Description("Ensure that adding null to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddNullShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - try - { - batch.Add(null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, null); - Assert.Fail(); - } - catch (ArgumentNullException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that adding multiple queries to the batch will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddMultiQueryShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Retrieve("foo", "bar"); - try - { - batch.Retrieve("foo", "bar2"); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that a batch that contains multiple operations on the same entity fails")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchWithMultipleOperationsOnSameEntityShouldFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ITableEntity first = GenerateRandomEnitity(pk); - batch.Insert(first); - - for (int m = 0; m < 99; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - // Insert Duplicate entity - batch.Insert(first); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, new string[] { "99:One of the request inputs is not valid." }, false); - } - } - - [TestMethod] - [Description("Ensure that a batch with over 100 entities will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOver100EntitiesShouldThrowAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - for (int m = 0; m < 101; m++) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - [TestMethod] - [Description("Ensure that a batch with entity over 1 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchEntityOver1MBShouldThrowAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity ent = GenerateRandomEnitity(pk); - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - - [TestMethod] - [Description("Ensure that a batch over 4 MB will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchOver4MBShouldThrowAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 65; m++) - { - DynamicTableEntity ent = GenerateRandomEnitity(pk); - - // Maximum Entity size is 64KB - ent.Properties.Add("binary", EntityProperty.GeneratePropertyForByteArray(new byte[64 * 1024])); - batch.Insert(ent); - } - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "ContentLengthExceeded" }, "The content length for the requested operation has exceeded the limit (4MB)."); - } - } - - [TestMethod] - [Description("Ensure that a query and one more operation will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchAddQueryAndOneMoreOperationShouldThrow() - { - TableBatchOperation batch = new TableBatchOperation(); - - try - { - batch.Add(TableOperation.Retrieve("foo", "bar")); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Add(TableOperation.Retrieve("foo", "bar")); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - batch.Clear(); - - try - { - batch.Add(TableOperation.Retrieve("foo", "bar")); - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - batch.Insert(0, TableOperation.Insert(GenerateRandomEnitity("foo"))); - batch.Insert(0, TableOperation.Retrieve("foo", "bar")); - - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - } - - // TODO fix me - //[TestMethod] - //[Description("Ensure that empty batch will throw")] - //[TestCategory(ComponentCategory.Table)] - //[TestCategory(TestTypeCategory.UnitTest)] - //[TestCategory(SmokeTestCategory.NonSmoke)] - //[TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - //public async Task TableBatchEmptyBatchShouldThrowAsync() - //{ - // TableBatchOperation batch = new TableBatchOperation(); - // await TestHelper.ExpectedExceptionAsync( - // async () => await currentTable.ExecuteBatchAsync(batch), - // "Empty batch operation should fail"); - //} - - [TestMethod] - [Description("Ensure that a given batch only allows entities with the same partitionkey")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableBatchLockToPartitionKey() - { - TableBatchOperation batch = new TableBatchOperation(); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - Assert.Fail(); - } - catch (ArgumentException) - { - // no op - } - catch (Exception) - { - Assert.Fail(); - } - - // should reset pk lock - batch.RemoveAt(0); - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - - try - { - batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2"))); - } - catch (ArgumentException) - { - Assert.Fail(); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("Ensure that a batch with an entity property over 255 chars will throw")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchWithPropertyOver255CharsShouldThrow() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - string propName = new string('a', 256); - - DynamicTableEntity ent = new DynamicTableEntity("foo", "bar"); - ent.Properties.Add(propName, new EntityProperty("propbar")); - batch.Insert(ent); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteBatchAsync(batch, null, opContext); - Assert.Fail(); - } - - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "PropertyNameTooLong" }, "The property name exceeds the maximum allowed length (255)."); - } - } - - #endregion - - #region Helpers - - private static void AddInsertToBatch(string pk, TableBatchOperation batch) - { - batch.Insert(GenerateRandomEnitity(pk)); - } - - private static DynamicTableEntity GenerateRandomEnitity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEntitySerializationTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEntitySerializationTests.cs deleted file mode 100644 index 465254cf31e49..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEntitySerializationTests.cs +++ /dev/null @@ -1,226 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableEntitySerializationTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableEntitySerializationTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public async Task MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public async Task MyTestCleanup() - { - await currentTable.DeleteIfExistsAsync(); - currentTable = null; - } - - #endregion - - [TestMethod] - [Description("A test checks basic function Reflection Serializer")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void ReflectionBasedSerializationTest() - { - ComplexEntity ent = new ComplexEntity(); - ComplexEntity secondEnt = new ComplexEntity(); - secondEnt.ReadEntity(ent.WriteEntity(null), null); - ComplexEntity.AssertEquality(ent, secondEnt); - } - - [TestMethod] - [Description("A test checks basic function Reflection Serializer")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void EntityPropertyTests() - { - Random rand = new Random(); - - // Binary - byte[] bytes = new byte[1024]; - rand.NextBytes(bytes); - - // Ctor - EntityProperty binProp = EntityProperty.GeneratePropertyForByteArray(bytes); - Assert.AreEqual(binProp.BinaryValue, bytes); - - // Setter - byte[] bytes2 = new byte[1024]; - rand.NextBytes(bytes2); - binProp.BinaryValue = bytes2; - Assert.AreEqual(binProp.BinaryValue, bytes2); - - // Null - binProp.BinaryValue = null; - Assert.AreEqual(binProp.BinaryValue, null); - - // bool - bool boolVal = true; - - // Ctor - EntityProperty boolProp = EntityProperty.GeneratePropertyForBool(boolVal); - Assert.AreEqual(boolProp.BooleanValue, boolVal); - - // Setter - bool boolVal2 = true; - boolProp.BooleanValue = boolVal2; - Assert.AreEqual(boolProp.BooleanValue, boolVal2); - - // DateTimeOffset - DateTimeOffset dto = DateTimeOffset.Now; - - // Ctor - EntityProperty dtoProp = EntityProperty.GeneratePropertyForDateTimeOffset(dto); - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto); - - // Setter - DateTimeOffset dto2 = DateTimeOffset.UtcNow; - dtoProp.DateTimeOffsetValue = dto2; - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto2); - - // Null - DateTimeOffset? dto3 = (DateTimeOffset?)null; - dtoProp.DateTimeOffsetValue = dto3; - Assert.AreEqual(dtoProp.DateTimeOffsetValue, dto3); - - // double - double doubleVal = 1234.4564; - - // Ctor - EntityProperty doubleProp = EntityProperty.GeneratePropertyForDouble(doubleVal); - Assert.AreEqual(doubleProp.DoubleValue, doubleVal); - - // Setter - double doubleVal2 = 8979654.35454; - doubleProp.DoubleValue = doubleVal2; - Assert.AreEqual(doubleProp.DoubleValue, doubleVal2); - - // Guid - Guid guidVal = new Guid(); - - // Ctor - EntityProperty guidProp = EntityProperty.GeneratePropertyForGuid(guidVal); - Assert.AreEqual(guidProp.GuidValue, guidVal); - - // Setter - Guid guidVal2 = new Guid(); - guidProp.GuidValue = guidVal2; - Assert.AreEqual(guidProp.GuidValue, guidVal2); - - // int - int intVal = 1234; - - // Ctor - EntityProperty intProp = EntityProperty.GeneratePropertyForInt(intVal); - Assert.AreEqual(intProp.Int32Value, intVal); - - // Setter - int intVal2 = 8979654; - intProp.Int32Value = intVal2; - Assert.AreEqual(intProp.Int32Value, intVal2); - - // long - long longVal = 123456789012; - - // Ctor - EntityProperty longProp = EntityProperty.GeneratePropertyForLong(longVal); - Assert.AreEqual(longProp.Int64Value, longVal); - - // Setter - long longVal2 = 56789012345; - longProp.Int64Value = longVal2; - Assert.AreEqual(longProp.Int64Value, longVal2); - - // string - string string1 = "abcdefghijklmnop"; - - // Ctor - EntityProperty stringProp = EntityProperty.GeneratePropertyForString(string1); - Assert.AreEqual(stringProp.StringValue, string1); - - // Setter - string string2 = "1234567890"; - stringProp.StringValue = string2; - Assert.AreEqual(stringProp.StringValue, string2); - - // Null - string string3 = null; - stringProp.StringValue = string3; - Assert.AreEqual(stringProp.StringValue, string3); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEscapingTaskTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEscapingTaskTests.cs deleted file mode 100644 index 8ec5422d6a527..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableEscapingTaskTests.cs +++ /dev/null @@ -1,359 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableEscapingTaskTests : TableTestBase - { - #region Locals + Ctors - public TableEscapingTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public async Task MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public async Task MyTestCleanup() - { - await currentTable.DeleteIfExistsAsync(); - } - - #endregion - - [TestMethod] - [Description("Escaping test for whitespace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingWhiteSpaceOnlyAsync() - { - await this.DoEscapeTestAsync(" ", false, true); - } - - [TestMethod] - [Description("Escaping test for whitespace in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingWhiteSpaceOnlyInBatchAsync() - { - await this.DoEscapeTestAsync(" ", true, true); - } - - [TestMethod] - [Description("Escaping test for EmptyString")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingEmptyStringAsync() - { - await this.DoEscapeTestAsync("", false, true); - } - - [TestMethod] - [Description("Escaping test for EmptyString in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingEmptyStringOnlyInBatchAsync() - { - await this.DoEscapeTestAsync("", true, true); - } - - [TestMethod] - [Description("Escaping test for RandomChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingRandomCharsAsync() - { - await this.DoEscapeTestAsync("!$'\"()*+,;=", false, false); - } - - [TestMethod] - [Description("Escaping test for RandomChars in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingRandomCharsInBatchAsync() - { - await this.DoEscapeTestAsync("!$'\"()*+,;=", true, false); - } - - [TestMethod] - [Description("Escaping test for Percent25")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingPercent25Async() - { - await this.DoEscapeTestAsync("foo%25", false, true); - } - - [TestMethod] - [Description("Escaping test for Percent25 in batch")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingPercent25InBatchAsync() - { - await this.DoEscapeTestAsync("foo%25", true, true); - } - - [TestMethod] - [Description("Escaping test for SpecialChars")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableEscapingSpecialCharsAsync() - { - await this.DoEscapeTestAsync("\\ // @ ? ", false, false); - await this.DoEscapeTestAsync("", false, false); - await this.DoEscapeTestAsync("", false, false); - await this.DoEscapeTestAsync("!<", false, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("", true, false); - await this.DoEscapeTestAsync("!<", true, false); - await this.DoEscapeTestAsync(" -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableOperationUnitTaskTests : TableTestBase - { - #region Locals + Ctors - public TableOperationUnitTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - // public static async Task MyClassInitialize(TestContext testContext) { } - // - // Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - // public static async Task MyClassCleanup() { } - // - // Use TestInitialize to run code before running each test - [TestInitialize()] - public async Task MyTestInitialize() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - } - - // - // Use TestCleanup to run code after each test has run - [TestCleanup()] - public async Task MyTestCleanup() - { - await currentTable.DeleteIfExistsAsync(); - } - - #endregion - - #region Insert - - [TestMethod] - [Description("TableOperation Insert")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - } - - [TestMethod] - [Description("TableOperation Insert Conflict")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertConflictAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - OperationContext opContext = new OperationContext(); - - // Attempt Insert Conflict Entity - DynamicTableEntity conflictEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - try - { - await currentTable.ExecuteAsync(TableOperation.Insert(conflictEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.Conflict, new string[] { "EntityAlreadyExists" }, "The specified entity already exists"); - } - } - - #endregion - - #region Insert Or Merge - - [TestMethod] - [Description("TableOperation Insert Or Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOrMerge() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Merge with no pre-existing entity - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity("insertOrMerge entity", "foo"); - insertOrMergeEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey); - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrMergeEntity.PartitionKey, insertOrMergeEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Insert Or Replace - - [TestMethod] - [Description("TableOperation Insert Or Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOrReplace() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Or Replace with no pre-existing entity - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity("insertOrReplace entity", "foo"); - insertOrReplaceEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrReplaceEntity.Properties.Count, retrievedEntity.Properties.Count); - - DynamicTableEntity replaceEntity = new DynamicTableEntity(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey); - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(insertOrReplaceEntity.PartitionKey, insertOrReplaceEntity.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - #endregion - - #region Delete - - [TestMethod] - [Description("TableOperation Delete")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationDeleteAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNotNull(result.Result); - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(ent)); - - // Retrieve Entity - TableResult result2 = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - [TestMethod] - [Description("TableOperation Delete Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationDeleteFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - OperationContext opContext = new OperationContext(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.ETag = "*"; - - try - { - await currentTable.ExecuteAsync(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - - - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - retrievedEntity.Properties["foo"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(retrievedEntity)); - - try - { - opContext = new OperationContext(); - // Now delete old reference with stale etag and validate exception - await currentTable.ExecuteAsync(TableOperation.Delete(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - } - - #endregion - - #region Merge - - [TestMethod] - [Description("TableOperation Merge")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationMergeAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(2, retrievedEntity.Properties.Count); - Assert.AreEqual(baseEntity.Properties["prop1"], retrievedEntity.Properties["prop1"]); - Assert.AreEqual(mergeEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Merge Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationMergeFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try merging with deleted entity - try - { - // Attempt a merge with stale etag - DynamicTableEntity mergeEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - mergeEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - #endregion - - #region Replace - - [TestMethod] - [Description("TableOperation Replace")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationReplaceAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - // ReplaceEntity - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(baseEntity.PartitionKey, baseEntity.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - } - - [TestMethod] - [Description("TableOperation Replace Fail")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationReplaceFailAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity baseEntity = new DynamicTableEntity("merge test", "foo"); - baseEntity.Properties.Add("prop1", new EntityProperty("value1")); - await currentTable.ExecuteAsync(TableOperation.Insert(baseEntity)); - - string staleEtag = baseEntity.ETag; - - // update entity to rev etag - baseEntity.Properties["prop1"].StringValue = "updated value"; - await currentTable.ExecuteAsync(TableOperation.Replace(baseEntity)); - - OperationContext opContext = new OperationContext(); - - try - { - // Attempt a merge with stale etag - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = staleEtag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, - 1, - (int)HttpStatusCode.PreconditionFailed, - new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, - new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); - } - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(baseEntity)); - - opContext = new OperationContext(); - - // try replacing with deleted entity - try - { - DynamicTableEntity replaceEntity = new DynamicTableEntity(baseEntity.PartitionKey, baseEntity.RowKey) { ETag = baseEntity.ETag }; - replaceEntity.Properties.Add("prop2", new EntityProperty("value2")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); - } - } - - #endregion - - #region Retrieve - - [TestMethod] - [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - - // not found - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - // Validate entity - Assert.AreEqual(sendEnt.Properties["String"], retrievedEntity.Properties["String"]); - Assert.AreEqual(sendEnt.Properties["Int64"], retrievedEntity.Properties["Int64"]); - Assert.AreEqual(sendEnt.Properties["Int64N"], retrievedEntity.Properties["Int64N"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitive"], retrievedEntity.Properties["LongPrimitive"]); - Assert.AreEqual(sendEnt.Properties["LongPrimitiveN"], retrievedEntity.Properties["LongPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Int32"], retrievedEntity.Properties["Int32"]); - Assert.AreEqual(sendEnt.Properties["Int32N"], retrievedEntity.Properties["Int32N"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitive"], retrievedEntity.Properties["IntegerPrimitive"]); - Assert.AreEqual(sendEnt.Properties["IntegerPrimitiveN"], retrievedEntity.Properties["IntegerPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Guid"], retrievedEntity.Properties["Guid"]); - Assert.AreEqual(sendEnt.Properties["GuidN"], retrievedEntity.Properties["GuidN"]); - Assert.AreEqual(sendEnt.Properties["Double"], retrievedEntity.Properties["Double"]); - Assert.AreEqual(sendEnt.Properties["DoubleN"], retrievedEntity.Properties["DoubleN"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitive"], retrievedEntity.Properties["DoublePrimitive"]); - Assert.AreEqual(sendEnt.Properties["DoublePrimitiveN"], retrievedEntity.Properties["DoublePrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["BinaryPrimitive"], retrievedEntity.Properties["BinaryPrimitive"]); - Assert.AreEqual(sendEnt.Properties["Binary"], retrievedEntity.Properties["Binary"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"], retrievedEntity.Properties["BoolPrimitive"]); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"], retrievedEntity.Properties["BoolPrimitiveN"]); - Assert.AreEqual(sendEnt.Properties["Bool"], retrievedEntity.Properties["Bool"]); - Assert.AreEqual(sendEnt.Properties["BoolN"], retrievedEntity.Properties["BoolN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"], retrievedEntity.Properties["DateTimeOffsetN"]); - Assert.AreEqual(sendEnt.Properties["DateTimeOffset"], retrievedEntity.Properties["DateTimeOffset"]); - Assert.AreEqual(sendEnt.Properties["DateTime"], retrievedEntity.Properties["DateTime"]); - Assert.AreEqual(sendEnt.Properties["DateTimeN"], retrievedEntity.Properties["DateTimeN"]); - } - - - [TestMethod] - [Description("A test to check batch retrieve functionality")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableBatchRetrieveWithResolverAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.PartitionKey = Guid.NewGuid().ToString(); - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // generate a set of properties for all supported Types - sendEnt.Properties = new ComplexEntity().WriteEntity(null); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - - EntityResolver resolver= (pk, rk, ts, props, etag) => pk + rk + props["foo"].StringValue + props.Count; - - // not found - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.NotFound); - Assert.IsNull(result.Result); - Assert.IsNull(result.Etag); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - // Success - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey, resolver)); - - Assert.AreEqual(result.HttpStatusCode, (int)HttpStatusCode.OK); - // Since there are properties in ComplexEntity set to null, we do not receive those from the server. Hence we need to check for non null values. - Assert.AreEqual((string)result.Result, sendEnt.PartitionKey + sendEnt.RowKey + sendEnt.Properties["foo"].StringValue + ComplexEntity.NumberOfNonNullProperties); - } - - [TestMethod] - [Description("A test to check ignore property attribute while serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveWithIgnoreAttributeWriteAsync() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - IgnoreEntity sendEnt = new IgnoreEntity(pk, rk); - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = true; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = DateTimeOffset.Now.AddMinutes(1); - - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(sendEnt.PartitionKey, sendEnt.RowKey)); - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("BoolPrimitiveNull")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("Bool")); - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.Properties["BoolPrimitive"].BooleanValue); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.Properties["BoolPrimitiveN"].BooleanValue); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.Properties["BoolN"].BooleanValue); - - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffset")); - Assert.IsFalse(retrievedEntity.Properties.ContainsKey("DateTimeOffsetNull")); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.Properties["DateTimeOffsetN"].DateTimeOffsetValue); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.Properties["DateTime"].DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.Properties["DateTimeN"].DateTime); - } - - [TestMethod] - [Description("A test to check ignore property attribute while de-serializing an entity")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveWithIgnoreAttributeReadAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - string pk = Guid.NewGuid().ToString(); - - // Add insert - DynamicTableEntity sendEnt = new DynamicTableEntity(); - sendEnt.Properties.Add("foo", new EntityProperty("bar")); - sendEnt.Properties.Add("Bool", new EntityProperty(true)); - sendEnt.Properties.Add("BoolN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolNull", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitive", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveN", new EntityProperty(true)); - sendEnt.Properties.Add("BoolPrimitiveNull", new EntityProperty(true)); - sendEnt.Properties.Add("DateTime", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeN", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeNull", new EntityProperty(DateTime.UtcNow.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffset", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetN", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - sendEnt.Properties.Add("DateTimeOffsetNull", new EntityProperty(DateTimeOffset.Now.AddMinutes(1))); - - sendEnt.PartitionKey = pk; - sendEnt.RowKey = Guid.NewGuid().ToString(); - - // insert entity - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, pk)); - IEnumerable result = await currentTable.ExecuteQuerySegmentedAsync(query, null); - IgnoreEntity retrievedEntity = result.ToList().First() as IgnoreEntity; - - Assert.AreEqual(sendEnt.Properties["BoolPrimitive"].BooleanValue, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.Properties["BoolPrimitiveN"].BooleanValue, retrievedEntity.BoolPrimitiveN); - Assert.AreNotEqual(sendEnt.Properties["BoolPrimitiveNull"].BooleanValue, retrievedEntity.BoolPrimitiveNull); - Assert.AreNotEqual(sendEnt.Properties["Bool"].BooleanValue, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.Properties["BoolN"].BooleanValue, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.Properties["BoolNull"].BooleanValue, retrievedEntity.BoolNull); - - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffset"].DateTimeOffsetValue, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.Properties["DateTimeOffsetN"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetN); - Assert.AreNotEqual(sendEnt.Properties["DateTimeOffsetNull"].DateTimeOffsetValue, retrievedEntity.DateTimeOffsetNull); - Assert.IsNull(retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.Properties["DateTime"].DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.Properties["DateTimeN"].DateTime, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.Properties["DateTimeNull"].DateTime, retrievedEntity.DateTimeNull); - } - - [TestMethod] - [Description("A test to check retrieve functionality Sync")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRetrieveSyncWithIgnoreAttributesAsync() - { - string pk = Guid.NewGuid().ToString(); - string rk = Guid.NewGuid().ToString(); - - IgnoreEntity sendEnt = new IgnoreEntity(pk, rk); - sendEnt.Bool = true; - sendEnt.BoolN = true; - sendEnt.BoolNull = null; - sendEnt.BoolPrimitive = true; - sendEnt.BoolPrimitiveN = true; - sendEnt.BoolPrimitiveNull = true; - sendEnt.DateTime = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeN = DateTime.UtcNow.AddMinutes(1); - sendEnt.DateTimeNull = null; - sendEnt.DateTimeOffset = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetN = DateTimeOffset.Now.AddMinutes(1); - sendEnt.DateTimeOffsetNull = DateTimeOffset.Now.AddMinutes(1); - - await currentTable.ExecuteAsync(TableOperation.Insert(sendEnt)); - - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, pk)); - - IEnumerable result = await currentTable.ExecuteQuerySegmentedAsync(query, null); - IgnoreEntity retrievedEntity = result.ToList().First() as IgnoreEntity; - - Assert.AreEqual(sendEnt.BoolPrimitive, retrievedEntity.BoolPrimitive); - Assert.AreEqual(sendEnt.BoolPrimitiveN, retrievedEntity.BoolPrimitiveN); - Assert.AreNotEqual(sendEnt.BoolPrimitiveNull, retrievedEntity.BoolPrimitiveNull); - Assert.AreNotEqual(sendEnt.Bool, retrievedEntity.Bool); - Assert.AreEqual(sendEnt.BoolN, retrievedEntity.BoolN); - Assert.AreEqual(sendEnt.BoolNull, retrievedEntity.BoolNull); - - Assert.AreNotEqual(sendEnt.DateTimeOffset, retrievedEntity.DateTimeOffset); - Assert.AreEqual(sendEnt.DateTimeOffsetN, retrievedEntity.DateTimeOffsetN); - Assert.AreNotEqual(sendEnt.DateTimeOffsetNull, retrievedEntity.DateTimeOffsetNull); - Assert.IsNull(retrievedEntity.DateTimeOffsetNull); - Assert.AreEqual(sendEnt.DateTime, retrievedEntity.DateTime); - Assert.AreEqual(sendEnt.DateTimeN, retrievedEntity.DateTimeN); - Assert.AreEqual(sendEnt.DateTimeNull, retrievedEntity.DateTimeNull); - } - #endregion - - #region Empty Keys Test - - [TestMethod] - [Description("TableOperations with Empty keys")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationsWithEmptyKeysAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = "", RowKey = "" }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - - // Retrieve Entity - TableResult result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - - DynamicTableEntity retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(ent.PartitionKey, retrievedEntity.PartitionKey); - Assert.AreEqual(ent.RowKey, retrievedEntity.RowKey); - Assert.AreEqual(ent.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(ent.Properties["foo"].StringValue, retrievedEntity.Properties["foo"].StringValue); - Assert.AreEqual(ent.Properties["foo"], retrievedEntity.Properties["foo"]); - Assert.AreEqual(ent.Properties["foo2"].StringValue, retrievedEntity.Properties["foo2"].StringValue); - Assert.AreEqual(ent.Properties["foo2"], retrievedEntity.Properties["foo2"]); - - // InsertOrMerge - DynamicTableEntity insertOrMergeEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrMergeEntity.Properties.Add("foo3", new EntityProperty("value")); - await currentTable.ExecuteAsync(TableOperation.InsertOrMerge(insertOrMergeEntity)); - - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(insertOrMergeEntity.Properties["foo3"], retrievedEntity.Properties["foo3"]); - - // InsertOrReplace - DynamicTableEntity insertOrReplaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey); - insertOrReplaceEntity.Properties.Add("prop2", new EntityProperty("otherValue")); - await currentTable.ExecuteAsync(TableOperation.InsertOrReplace(insertOrReplaceEntity)); - - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(1, retrievedEntity.Properties.Count); - Assert.AreEqual(insertOrReplaceEntity.Properties["prop2"], retrievedEntity.Properties["prop2"]); - - // Merge - DynamicTableEntity mergeEntity = new DynamicTableEntity(retrievedEntity.PartitionKey, retrievedEntity.RowKey) { ETag = retrievedEntity.ETag }; - mergeEntity.Properties.Add("mergeProp", new EntityProperty("merged")); - await currentTable.ExecuteAsync(TableOperation.Merge(mergeEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(mergeEntity.Properties["mergeProp"], retrievedEntity.Properties["mergeProp"]); - - // Replace - DynamicTableEntity replaceEntity = new DynamicTableEntity(ent.PartitionKey, ent.RowKey) { ETag = retrievedEntity.ETag }; - replaceEntity.Properties.Add("replaceProp", new EntityProperty("replace")); - await currentTable.ExecuteAsync(TableOperation.Replace(replaceEntity)); - - // Retrieve Entity & Verify Contents - result = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - retrievedEntity = result.Result as DynamicTableEntity; - Assert.IsNotNull(retrievedEntity); - Assert.AreEqual(replaceEntity.Properties.Count, retrievedEntity.Properties.Count); - Assert.AreEqual(replaceEntity.Properties["replaceProp"], retrievedEntity.Properties["replaceProp"]); - - // Delete Entity - await currentTable.ExecuteAsync(TableOperation.Delete(retrievedEntity)); - - // Retrieve Entity - TableResult result2 = await currentTable.ExecuteAsync(TableOperation.Retrieve(ent.PartitionKey, ent.RowKey)); - Assert.IsNull(result2.Result); - } - - #endregion - - #region Insert Negative Tests - - [TestMethod] - [Description("TableOperation Insert Entity over 1 MB")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableOperationInsertOver1MBAsync() - { - CloudTableClient tableClient = GenerateCloudTableClient(); - - // Insert Entity - DynamicTableEntity ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; - ent.Properties.Add("foo2", new EntityProperty("bar2")); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("largeprop", EntityProperty.GeneratePropertyForByteArray(new byte[1024 * 1024])); - - OperationContext opContext = new OperationContext(); - try - { - - await currentTable.ExecuteAsync(TableOperation.Insert(ent), null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); - } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryGenericTaskTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryGenericTaskTests.cs deleted file mode 100644 index ded24ac9332eb..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryGenericTaskTests.cs +++ /dev/null @@ -1,525 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryGenericTaskTests : TableTestBase - { - #region Locals + Ctors - public TableQueryGenericTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - BaseEntity ent = GenerateRandomEnitity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - await currentTable.ExecuteBatchAsync(batch); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - await currentTable.DeleteIfExistsAsync(); - } - // - // Use TestInitialize to run code before running each test - //[TestInitialize()] - //public void MyTestInitialize(){} - // - // Use TestCleanup to run code after each test has run - //[TestCleanup()] - // public void MyTestCleanup(){} - - #endregion - - #region Unit Tests - - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryBasicAsync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); - - foreach (BaseEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - ent.Validate(); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryWithContinuationAsync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - - int count = 0; - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); - - foreach (BaseEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - ent.Validate(); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithFilter() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - ent.Validate(); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryProjection() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("Basic with resolver")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericWithResolver() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - - foreach (string ent in ExecuteQuery(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - - foreach (BaseEntity ent in ExecuteQuery(currentTable, query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - Assert.IsNotNull(ent.ETag); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("Basic resolver test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryResolverWithDynamic() - { - TableQuery query = new TableQuery().Select(new List() { "A", "C" }); - foreach (string ent in ExecuteQueryWithResolver(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue)) - { - Assert.AreEqual(ent, "ac"); - } - foreach (BaseEntity ent in ExecuteQueryWithResolver(currentTable, query, - (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, ETag = etag })) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.A, "a"); - Assert.IsNull(ent.B); - Assert.AreEqual(ent.C, "c"); - Assert.IsNull(ent.D); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryOnSupportedTypesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - ComplexEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - batch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.LongPrimitive), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Double), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Int32), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.DateTimeOffset), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.BinaryPrimitive), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Binary)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); - - - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - #endregion - - #region Negative Tests - - [TestMethod] - [Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableGenericQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static List ExecuteQuery(CloudTable table, TableQuery query) where T: ITableEntity, new() - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, currSeg != null ? currSeg.ContinuationToken : null)); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static List ExecuteQueryWithResolver(CloudTable table, TableQuery query, EntityResolver resolver) - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, resolver, currSeg != null ? currSeg.ContinuationToken : null)); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - - } - - return retList; - } - - private static List ExecuteQuery(CloudTable table, TableQuery query, EntityResolver resolver) where T : ITableEntity, new() - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, resolver, currSeg != null ? currSeg.ContinuationToken : null)); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, ExecuteQuery(table, new TableQuery().Where(filter)).Count()); - } - - private static BaseEntity GenerateRandomEnitity(string pk) - { - BaseEntity ent = new BaseEntity(); - ent.Populate(); - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryTaskTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryTaskTests.cs deleted file mode 100644 index 85195d1cbec6f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryTaskTests.cs +++ /dev/null @@ -1,601 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using Microsoft.WindowsAzure.Storage.Table.Entities; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryTaskTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableQueryTaskTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - DynamicTableEntity ent = GenerateRandomEntity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - await currentTable.ExecuteBatchAsync(batch); - } - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - await currentTable.DeleteIfExistsAsync(); - } - // - // Use TestInitialize to run code before running each test - //[TestInitialize()] - //public void MyTestInitialize(){} - // - // Use TestCleanup to run code after each test has run - //[TestCleanup()] - // public void MyTestCleanup(){} - - #endregion - - #region Unit Tests - - [TestMethod] - [Description("A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryBasicAsync() - { - TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); - - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryWithContinuationAsync() - { - TableQuery query = new TableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - - [TestMethod] - [Description("A test to validate basic table filtering")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithFilterAsync() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); - - OperationContext opContext = new OperationContext(); - int count = 0; - - foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.AreEqual(ent.Properties["foo"].StringValue, "bar"); - - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryProjectionAsync() - { - TableQuery query = new TableQuery().Select(new List() { "a", "c" }); - - foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.Properties["a"].StringValue, "a"); - Assert.IsFalse(ent.Properties.ContainsKey("b")); - Assert.AreEqual(ent.Properties["c"].StringValue, "c"); - Assert.IsFalse(ent.Properties.ContainsKey("d")); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryOnSupportedTypesAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.Properties["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - } - finally - { - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("A test validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableRegionalQueryOnSupportedTypesAsync() - { - CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); - - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - try - { - // Setup - TableBatchOperation batch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - DynamicTableEntity middleRef = null; - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.IntegerPrimitive = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); - dynEnt.Properties = complexEntity.WriteEntity(null); - batch.Insert(dynEnt); - - if (m == 50) - { - middleRef = dynEnt; - } - - // Add delay to make times unique - await Task.Delay(100); - } - - await table.ExecuteBatchAsync(batch); - - // 1. Filter on String - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); - - // 2. Filter on Guid - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1); - - // 3. Filter on Long - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); - - // 4. Filter on Double - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Double"].DoubleValue.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50); - - // 5. Filter on Integer - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Int32"].Int32Value.Value), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50); - - // 6. Filter on Date - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50); - - // 7. Filter on Boolean - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value), - 50); - - // 8. Filter on Binary - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1); - - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, - middleRef.Properties["BinaryPrimitive"].BinaryValue), 1); - - // 9. Filter on Binary GTE - ExecuteQueryAndAssertResults(table, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - - // 10. Complex Filter on Binary GTE - ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( - TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, - middleRef.PartitionKey), - TableOperators.And, - TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, - middleRef.Properties["Binary"].BinaryValue)), 50); - - ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", - QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); - } - finally - { - Thread.CurrentThread.CurrentCulture = currentCulture; - table.DeleteIfExistsAsync().Wait(); - } - } - - [TestMethod] - [Description("A test to validate querying with an empty value")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryEmptyValueAsync() - { - CloudTableClient client = GenerateCloudTableClient(); - - CloudTable table = client.GetTableReference(GenerateRandomTableName()); - await table.CreateAsync(); - - // Setup - string pk = Guid.NewGuid().ToString(); - - DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey"); - dynEnt.Properties.Add("A", new EntityProperty(string.Empty)); - await table.ExecuteAsync(TableOperation.Insert(dynEnt)); - - // 1. Filter on String - List results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); - Assert.AreEqual(1, results.Count); - - List pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); - Assert.AreEqual(1, pocoresults.Count); - } - #endregion - - #region Negative Tests - - [TestMethod] - [Description("A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryWithInvalidTakeCount() - { - try - { - TableQuery query = new TableQuery().Take(0); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - TableQuery query = new TableQuery().Take(-1); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - - [TestMethod] - [Description("A test to invalid query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public async Task TableQueryWithInvalidQuery() - { - TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); - - OperationContext opContext = new OperationContext(); - try - { - await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); - Assert.Fail(); - } - catch (Exception) - { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); - } - } - - #endregion - - #region Helpers - - private static List ExecuteQuery(CloudTable table, TableQuery query) - { - List retList = new List(); - - TableQuerySegment currSeg = null; - - while (currSeg == null || currSeg.ContinuationToken != null) - { - Task> task = Task.Run(() => table.ExecuteQuerySegmentedAsync(query, currSeg != null ? currSeg.ContinuationToken : null)); - task.Wait(); - currSeg = task.Result; - retList.AddRange(currSeg.Results); - } - - return retList; - } - - private static void ExecuteQueryAndAssertResults(CloudTable table, string filter, int expectedResults) - { - Assert.AreEqual(expectedResults, ExecuteQuery(table, new TableQuery().Where(filter)).Count()); - } - - private static DynamicTableEntity GenerateRandomEntity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("foo", new EntityProperty("bar")); - ent.Properties.Add("a", new EntityProperty("a")); - ent.Properties.Add("b", new EntityProperty("b")); - ent.Properties.Add("c", new EntityProperty("c")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryableTests.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryableTests.cs deleted file mode 100644 index 6c6263c63a895..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableQueryableTests.cs +++ /dev/null @@ -1,800 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -#if WINDOWS_DESKTOP -using Microsoft.VisualStudio.TestTools.UnitTesting; -#else -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -#endif - -using Microsoft.WindowsAzure.Storage.Table.Entities; -using Microsoft.WindowsAzure.Storage.Table.Queryable; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - [TestClass] - public class TableQueryableTests : TableTestBase - { - readonly CloudTableClient DefaultTableClient = new CloudTableClient(new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint), TestBase.StorageCredentials); - - #region Locals + Ctors - public TableQueryableTests() - { - } - - private TestContext testContextInstance; - - /// - ///Gets or sets the test context which provides - ///information about and functionality for the current test run. - /// - public TestContext TestContext - { - get - { - return testContextInstance; - } - set - { - testContextInstance = value; - } - } - - static CloudTable currentTable = null; - static CloudTable complexEntityTable = null; - static ComplexEntity middleRef = null; - #endregion - - #region Additional test attributes - // - // You can use the following additional attributes as you write your tests: - // - // Use ClassInitialize to run code before running the first test in the class - [ClassInitialize()] - public static async Task MyClassInitialize(TestContext testContext) - { - CloudTableClient tableClient = GenerateCloudTableClient(); - currentTable = tableClient.GetTableReference(GenerateRandomTableName()); - await currentTable.CreateIfNotExistsAsync(); - - // Bulk Query Entities - for (int i = 0; i < 15; i++) - { - TableBatchOperation batch = new TableBatchOperation(); - - for (int j = 0; j < 100; j++) - { - var ent = GenerateRandomEnitity("tables_batch_" + i.ToString()); - ent.RowKey = string.Format("{0:0000}", j); - batch.Insert(ent); - } - - await currentTable.ExecuteBatchAsync(batch); - } - - - complexEntityTable = tableClient.GetTableReference(GenerateRandomTableName()); - await complexEntityTable.CreateAsync(); - - // Setup - TableBatchOperation complexBatch = new TableBatchOperation(); - string pk = Guid.NewGuid().ToString(); - - for (int m = 0; m < 100; m++) - { - ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); - complexEntity.String = string.Format("{0:0000}", m); - complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; - complexEntity.Bool = m % 2 == 0 ? true : false; - complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; - complexEntity.Double = m + ((double)m / 100); - complexEntity.DoublePrimitive = m + ((double)m / 100); - complexEntity.Int32 = m; - complexEntity.Int32N = m; - complexEntity.IntegerPrimitive = m; - complexEntity.IntegerPrimitiveN = m; - complexEntity.Int64 = (long)int.MaxValue + m; - complexEntity.LongPrimitive = (long)int.MaxValue + m; - complexEntity.LongPrimitiveN = (long)int.MaxValue + m; - complexEntity.Guid = Guid.NewGuid(); - - complexBatch.Insert(complexEntity); - - if (m == 50) - { - middleRef = complexEntity; - } - - // Add delay to make times unique - Thread.Sleep(100); - } - - await complexEntityTable.ExecuteBatchAsync(complexBatch); - } - // - // Use ClassCleanup to run code after all tests in a class have run - [ClassCleanup()] - public static async Task MyClassCleanup() - { - await currentTable.DeleteIfExistsAsync(); - await complexEntityTable.DeleteIfExistsAsync(); - } - // - // Use TestInitialize to run code before running each test - //[TestInitialize()] - //public void MyTestInitialize(){} - // - // Use TestCleanup to run code after each test has run - //[TestCleanup()] - // public void MyTestCleanup(){} - - #endregion - - #region Unit Tests - #region Query Segmented - -#if SYNC - #region Sync - [TestMethod] - [Description("IQueryable - A test to validate basic table query")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableBasicSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - - TableQuerySegment seg = query.ExecuteSegmented(null); - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table continuation")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithContinuationSync() - { - TableQuery query = (from ent in currentTable.CreateQuery() - select ent).AsTableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = query.ExecuteSegmented(null, null, opContext); - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - seg = query.ExecuteSegmented(seg.ContinuationToken, null, opContext); - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion -#endif - #region APM - - [TestMethod] - [Description("IQueryable - A test to validate basic table query APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryableBasicAPM() - { - TableQuery query = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" - select ent).AsTableQuery(); - - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(null, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.Properties.Count, 4); - } - } - - [TestMethod] - [Description("IQueryable - A test to validate basic table continuation APM")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableGenericQueryableWithContinuationAPM() - { - TableQuery query = (from ent in currentTable.CreateQuery() - select ent).AsTableQuery(); - - OperationContext opContext = new OperationContext(); - TableQuerySegment seg = null; - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(null, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - int count = 0; - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - // Second segment - Assert.IsNotNull(seg.ContinuationToken); - using (ManualResetEvent evt = new ManualResetEvent(false)) - { - IAsyncResult asyncRes = null; - query.BeginExecuteSegmented(seg.ContinuationToken, null, opContext, (res) => - { - asyncRes = res; - evt.Set(); - }, null); - evt.WaitOne(); - - seg = query.EndExecuteSegmented(asyncRes); - } - - foreach (DynamicTableEntity ent in seg) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - count++; - } - - Assert.AreEqual(1500, count); - TestHelper.AssertNAttempts(opContext, 2); - } - #endregion - - #endregion - - [TestMethod] - [Description("IQueryable DynamicTableEntityQuery")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableDynamicTableEntityQuery() - { - OperationContext opContext = new OperationContext(); - - Func identityFunc = (s) => s; - - TableQuery res = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.Properties[identityFunc("DateTimeOffset")].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent).WithContext(opContext); - - List entities = res.ToList(); - - Assert.AreEqual(entities.Count, 50); - } - - [TestMethod] - [Description("IQueryable Where")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWhere() - { - OperationContext opContext = new OperationContext(); - - TableQuery res = (from ent in currentTable.CreateQuery() - where ent.PartitionKey == "tables_batch_1" && - ent.RowKey.CompareTo("0050") >= 0 - select ent).WithContext(opContext); - - - int count = 0; - foreach (DynamicTableEntity ent in res) - { - Assert.AreEqual(ent.Properties["test"].StringValue, "test"); - - Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); - Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); - count++; - } - - Assert.AreEqual(count, 50); - } - - [TestMethod] - [Description("TableQueryable - A test to validate basic table continuation & query is able to correctly execute multiple times")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableEnumerateTwice() - { - OperationContext opContext = new OperationContext(); - TableQuery res = (from ent in currentTable.CreateQuery() - select ent).WithContext(opContext); - - List firstIteration = new List(); - List secondIteration = new List(); - - foreach (DynamicTableEntity ent in res) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - firstIteration.Add(ent); - } - - foreach (DynamicTableEntity ent in res) - { - Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); - Assert.AreEqual(ent.Properties.Count, 4); - secondIteration.Add(ent); - } - - Assert.AreEqual(firstIteration.Count, secondIteration.Count); - - for (int m = 0; m < firstIteration.Count; m++) - { - Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey); - Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey); - Assert.AreEqual(firstIteration[m].Properties.Count, secondIteration[m].Properties.Count); - Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp); - Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag); - } - } - - [TestMethod] - [Description("IQueryable Basic projection test")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableProjection() - { - OperationContext opContext = new OperationContext(); - var baseQuery = currentTable.CreateQuery().WithContext(opContext); - - var pocoRes = (from ent in baseQuery - select new ProjectedPOCO() - { - PartitionKey = ent.PartitionKey, - RowKey = ent.RowKey, - Timestamp = ent.Timestamp, - a = ent.a, - c = ent.c - }); - int count = 0; - - foreach (ProjectedPOCO ent in pocoRes) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.a, "a"); - Assert.IsNull(ent.b); - Assert.AreEqual(ent.c, "c"); - Assert.IsNull(ent.d); - count++; - } - - // Project a single property via Select - var stringRes = (from ent in baseQuery - select ent.b).ToList(); - - Assert.AreEqual(stringRes.Count, count); - - - // TableQuery.Project no resolver - IQueryable projectionResult = (from ent in baseQuery - select TableQuery.Project(ent, "a", "b")); - count = 0; - foreach (POCOEntity ent in projectionResult) - { - Assert.IsNotNull(ent.PartitionKey); - Assert.IsNotNull(ent.RowKey); - Assert.IsNotNull(ent.Timestamp); - - Assert.AreEqual(ent.a, "a"); - Assert.AreEqual(ent.b, "b"); - Assert.IsNull(ent.c); - Assert.IsNull(ent.test); - count++; - } - - Assert.AreEqual(stringRes.Count, count); - - // TableQuery.Project no resolver - IQueryable resolverRes = (from ent in baseQuery - select TableQuery.Project(ent, "a", "b")).Resolve((pk, rk, ts, props, etag) => props["a"].StringValue); - count = 0; - foreach (string s in resolverRes) - { - Assert.AreEqual(s, "a"); - count++; - } - - Assert.AreEqual(stringRes.Count, count); - } - - [TestMethod] - [Description("IQueryable - validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableOnSupportedTypes() - { - // 1. Filter on String - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.String.CompareTo("0050") >= 0 - select ent); - - Assert.AreEqual(50, stringQuery.AsTableQuery().Execute().Count()); - - // 2. Filter on Guid - var guidQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Guid == middleRef.Guid - select ent); - - Assert.AreEqual(1, guidQuery.AsTableQuery().Execute().Count()); - - - // 3. Filter on Long - var longQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Int64 >= middleRef.Int64 - select ent); - - Assert.AreEqual(50, longQuery.AsTableQuery().Execute().Count()); - - var longPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.LongPrimitive >= middleRef.LongPrimitive - select ent); - - Assert.AreEqual(50, longPrimitiveQuery.AsTableQuery().Execute().Count()); - - var longNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.LongPrimitiveN >= middleRef.LongPrimitiveN - select ent); - - Assert.AreEqual(50, longNullableQuery.AsTableQuery().Execute().Count()); - - // 4. Filter on Double - var doubleQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Double >= middleRef.Double - select ent); - - Assert.AreEqual(50, doubleQuery.AsTableQuery().Execute().Count()); - - var doubleNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.DoublePrimitive >= middleRef.DoublePrimitive - select ent); - - Assert.AreEqual(50, doubleNullableQuery.AsTableQuery().Execute().Count()); - - - // 5. Filter on Integer - var int32Query = (from ent in complexEntityTable.CreateQuery() - where ent.Int32 >= middleRef.Int32 - select ent); - - Assert.AreEqual(50, int32Query.AsTableQuery().Execute().Count()); - - var int32NullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Int32N >= middleRef.Int32N - select ent); - - Assert.AreEqual(50, int32NullableQuery.AsTableQuery().Execute().Count()); - - - // 6. Filter on Date - var dtoQuery = (from ent in complexEntityTable.CreateQuery() - where ent.DateTimeOffset >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, dtoQuery.AsTableQuery().Execute().Count()); - - // 7. Filter on Boolean - var boolQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Bool == middleRef.Bool - select ent); - - Assert.AreEqual(50, boolQuery.AsTableQuery().Execute().Count()); - - var boolPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.BoolPrimitive == middleRef.BoolPrimitive - select ent); - - Assert.AreEqual(50, boolPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 8. Filter on Binary - var binaryQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Binary == middleRef.Binary - select ent); - - Assert.AreEqual(1, binaryQuery.AsTableQuery().Execute().Count()); - - var binaryPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.BinaryPrimitive == middleRef.BinaryPrimitive - select ent); - - Assert.AreEqual(1, binaryPrimitiveQuery.AsTableQuery().Execute().Count()); - - - // 10. Complex Filter on Binary GTE - - var complexFilter = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.String.CompareTo("0050") >= 0 && - ent.Int64 >= middleRef.Int64 && - ent.LongPrimitive >= middleRef.LongPrimitive && - ent.LongPrimitiveN >= middleRef.LongPrimitiveN && - ent.Int32 >= middleRef.Int32 && - ent.Int32N >= middleRef.Int32N && - ent.DateTimeOffset >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, complexFilter.AsTableQuery().Execute().Count()); - } - - [TestMethod] - [Description("IQueryable - validate all supported query types")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableOnSupportedTypesViaDynamicTableEntity() - { - // 1. Filter on String - var stringQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["String"].StringValue.CompareTo("0050") >= 0 - select ent); - - Assert.AreEqual(50, stringQuery.AsTableQuery().Execute().Count()); - - // 2. Filter on Guid - var guidQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Guid"].GuidValue == middleRef.Guid - select ent); - - Assert.AreEqual(1, guidQuery.AsTableQuery().Execute().Count()); - - - // 3. Filter on Long - var longQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int64"].Int64Value >= middleRef.Int64 - select ent); - - Assert.AreEqual(50, longQuery.AsTableQuery().Execute().Count()); - - var longPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["LongPrimitive"].Int64Value >= middleRef.LongPrimitive - select ent); - - Assert.AreEqual(50, longPrimitiveQuery.AsTableQuery().Execute().Count()); - - var longNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["LongPrimitiveN"].Int64Value >= middleRef.LongPrimitiveN - select ent); - - Assert.AreEqual(50, longNullableQuery.AsTableQuery().Execute().Count()); - - // 4. Filter on Double - var doubleQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Double"].DoubleValue >= middleRef.Double - select ent); - - Assert.AreEqual(50, doubleQuery.AsTableQuery().Execute().Count()); - - var doubleNullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["DoublePrimitive"].DoubleValue >= middleRef.DoublePrimitive - select ent); - - Assert.AreEqual(50, doubleNullableQuery.AsTableQuery().Execute().Count()); - - - // 5. Filter on Integer - var int32Query = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int32"].Int32Value >= middleRef.Int32 - select ent); - - Assert.AreEqual(50, int32Query.AsTableQuery().Execute().Count()); - - var int32NullableQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Int32N"].Int32Value >= middleRef.Int32N - select ent); - - Assert.AreEqual(50, int32NullableQuery.AsTableQuery().Execute().Count()); - - - // 6. Filter on Date - var dtoQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["DateTimeOffset"].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, dtoQuery.AsTableQuery().Execute().Count()); - - // 7. Filter on Boolean - var boolQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Bool"].BooleanValue == middleRef.Bool - select ent); - - Assert.AreEqual(50, boolQuery.AsTableQuery().Execute().Count()); - - var boolPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["BoolPrimitive"].BooleanValue == middleRef.BoolPrimitive - select ent); - - Assert.AreEqual(50, boolPrimitiveQuery.AsTableQuery().Execute().Count()); - - // 8. Filter on Binary - var binaryQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["Binary"].BinaryValue == middleRef.Binary - select ent); - - Assert.AreEqual(1, binaryQuery.AsTableQuery().Execute().Count()); - - var binaryPrimitiveQuery = (from ent in complexEntityTable.CreateQuery() - where ent.Properties["BinaryPrimitive"].BinaryValue == middleRef.BinaryPrimitive - select ent); - - Assert.AreEqual(1, binaryPrimitiveQuery.AsTableQuery().Execute().Count()); - - - // 10. Complex Filter on Binary GTE - var complexFilter = (from ent in complexEntityTable.CreateQuery() - where ent.PartitionKey == middleRef.PartitionKey && - ent.Properties["String"].StringValue.CompareTo("0050") >= 0 && - ent.Properties["Int64"].Int64Value >= middleRef.Int64 && - ent.Properties["LongPrimitive"].Int64Value >= middleRef.LongPrimitive && - ent.Properties["LongPrimitiveN"].Int64Value >= middleRef.LongPrimitiveN && - ent.Properties["Int32"].Int32Value >= middleRef.Int32 && - ent.Properties["Int32N"].Int32Value >= middleRef.Int32N && - ent.Properties["DateTimeOffset"].DateTimeOffsetValue >= middleRef.DateTimeOffset - select ent); - - Assert.AreEqual(50, complexFilter.AsTableQuery().Execute().Count()); - } - #endregion - - #region Negative Tests - - [TestMethod] - [Description("IQueryable - A test with invalid take count")] - [TestCategory(ComponentCategory.Table)] - [TestCategory(TestTypeCategory.UnitTest)] - [TestCategory(SmokeTestCategory.NonSmoke)] - [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] - public void TableQueryableWithInvalidTakeCount() - { - try - { - var stringQuery = (from ent in currentTable.CreateQuery() - where ent.String.CompareTo("0050") > 0 - select ent).Take(0).ToList(); - - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - - try - { - var stringQuery = (from ent in currentTable.CreateQuery() - where ent.String.CompareTo("0050") > 0 - select ent).Take(-1).ToList(); - Assert.Fail(); - } - catch (ArgumentException ex) - { - Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); - } - catch (Exception) - { - Assert.Fail(); - } - } - #endregion - - #region Helpers - - private static DynamicTableEntity GenerateRandomEnitity(string pk) - { - DynamicTableEntity ent = new DynamicTableEntity(); - ent.Properties.Add("test", new EntityProperty("test")); - ent.Properties.Add("a", new EntityProperty("a")); - ent.Properties.Add("b", new EntityProperty("b")); - ent.Properties.Add("c", new EntityProperty("c")); - - ent.PartitionKey = pk; - ent.RowKey = Guid.NewGuid().ToString(); - return ent; - } - - internal class POCOEntity : TableEntity - { - public string test { get; set; } - public string a { get; set; } - public string b { get; set; } - public string c { get; set; } - } - - internal class ProjectedPOCO : TableEntity - { - public string test { get; set; } - public string a { get; set; } - public string b { get; set; } - public string c { get; set; } - public string d { get; set; } - } - #endregion - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableTestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableTestBase.cs deleted file mode 100644 index de7c4b85f841f..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/Table/TableTestBase.cs +++ /dev/null @@ -1,41 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using System; -using System.Text; - -namespace Microsoft.WindowsAzure.Storage.Table -{ - public class TableTestBase : TestBase - { - public static string GenerateRandomTableName() - { - return "tbl" + Guid.NewGuid().ToString("N"); - } - - public static string GenerateRandomStringFromCharset(int tableNameLength, string legalChars, Random rand) - { - StringBuilder retString = new StringBuilder(); - for (int n = 0; n < tableNameLength; n++) - { - retString.Append(legalChars[rand.Next(legalChars.Length - 1)]); - } - - return retString.ToString(); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestBase.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestBase.cs deleted file mode 100644 index 301a209bd135b..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestBase.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -namespace Microsoft.WindowsAzure.Storage -{ - using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; - using Microsoft.WindowsAzure.Storage.Auth; - using System.Xml.Linq; - - [TestClass] - public partial class TestBase - { - static TestBase() - { - XElement element = XElement.Load(TestConfigurations.DefaultTestConfigFilePath); - TestConfigurations = TestConfigurations.ReadFromXml(element); - - foreach (TenantConfiguration tenant in TestConfigurations.TenantConfigurations) - { - if (tenant.TenantName == TestConfigurations.TargetTenantName) - { - TargetTenantConfig = tenant; - break; - } - } - - StorageCredentials = new StorageCredentials(TargetTenantConfig.AccountName, - TargetTenantConfig.AccountKey); - - CurrentTenantType = TargetTenantConfig.TenantType; - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestHelper.cs b/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestHelper.cs deleted file mode 100644 index c5856968ec66d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/TestHelper.cs +++ /dev/null @@ -1,113 +0,0 @@ -// ----------------------------------------------------------------------------------------- -// -// Copyright 2012 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. -// -// ----------------------------------------------------------------------------------------- - -using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; -using System; -using System.IO; -using System.Net; -using System.Threading.Tasks; - -namespace Microsoft.WindowsAzure.Storage -{ - public partial class TestHelper - { - /// - /// Compares the streams from the current position to the end. - /// - internal static async Task AssertStreamsAreEqualAsync(Stream src, Stream dst) - { - Assert.AreEqual(src.Length, dst.Length); - - byte[] srcBuffer = new byte[64 * 1024]; - int srcRead; - - byte[] dstBuffer = new byte[64 * 1024]; - int dstRead; - - do - { - srcRead = await src.ReadAsync(srcBuffer, 0, srcBuffer.Length); - dstRead = await dst.ReadAsync(dstBuffer, 0, dstBuffer.Length); - - Assert.AreEqual(srcRead, dstRead); - - for (int i = 0; i < srcRead; i++) - { - Assert.AreEqual(srcBuffer[i], dstBuffer[i]); - } - } - while (srcRead > 0); - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static async Task ExpectedExceptionAsync(Func operation, string operationDescription) - where T : Exception - { - try - { - await operation(); - } - catch (T e) - { - return e; - } - catch (Exception ex) - { - T e = ex as T; // Test framework changes the value under debugger - if (e != null) - { - return e; - } - Assert.Fail("Invalid exception {0} for operation: {1}", ex.GetType(), operationDescription); - } - - Assert.Fail("No exception received while while expecting {0}: {1}", typeof(T).ToString(), operationDescription); - return null; - } - - /// - /// Runs a given operation that is expected to throw an exception. - /// - /// - /// - /// - internal static async Task ExpectedExceptionAsync(Func operation, OperationContext operationContext, string operationDescription, HttpStatusCode expectedStatusCode, string requestErrorCode = null) - { - try - { - await operation(); - } - catch (Exception) - { - Assert.AreEqual((int)expectedStatusCode, operationContext.LastResult.HttpStatusCode, "Http status code is unexpected."); - if (!string.IsNullOrEmpty(requestErrorCode)) - { - Assert.IsNotNull(operationContext.LastResult.ExtendedErrorInformation); - Assert.AreEqual(requestErrorCode, operationContext.LastResult.ExtendedErrorInformation.ErrorCode); - } - return; - } - - Assert.Fail("No exception received while while expecting {0}: {1}", expectedStatusCode, operationDescription); - } - } -} diff --git a/microsoft-azure-api/Services/Storage/Test/Unit/WP/WP.csproj b/microsoft-azure-api/Services/Storage/Test/Unit/WP/WP.csproj deleted file mode 100644 index 103c6e303aa1d..0000000000000 --- a/microsoft-azure-api/Services/Storage/Test/Unit/WP/WP.csproj +++ /dev/null @@ -1,226 +0,0 @@ - - - - Debug - x86 - 10.0.20506 - 2.0 - {9456513A-1DDD-44E8-9FF0-985317F29A50} - {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Microsoft.WindowsAzure.Storage - Microsoft.WindowsAzure.Storage.Test - WindowsPhone - v8.0 - $(TargetFrameworkVersion) - true - true - - - true - true - Microsoft_WindowsAzure_Storage_$(Configuration)_$(Platform).xap - Properties\AppManifest.xml - Microsoft.WindowsAzure.Storage.App - false - 11.0 - true - - - true - full - false - Bin\x86\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\x86\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - true - full - false - Bin\ARM\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\ARM\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - Bin\Release\ - WINDOWS_PHONE - - - WINDOWS_PHONE - Bin\Debug\ - - - - - - Blob\Blob - - - Core\Core - - - Queue\Queue - - - Table\Table - - - Table\Entities\Table - - - TestConfigProcess\TestConfigProcess - - - - - Table\Entities\Entities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Readme.txt - - - TestConfigurations.xml - Always - Designer - - - - - App.xaml - - - - - - MainPage.xaml - - - - True - True - AppResources.resx - - - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - - Designer - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - PublicResXFileCodeGenerator - AppResources.Designer.cs - - - - - {CF1D432A-380F-434A-BC43-FC39AC8B61A8} - WP %28Lib\WP%29 - - - - - - - \ No newline at end of file diff --git a/microsoft-azure-api/Services/Storage/changelog.txt b/microsoft-azure-api/Services/Storage/changelog.txt deleted file mode 100644 index 4b3856f29a2ff..0000000000000 --- a/microsoft-azure-api/Services/Storage/changelog.txt +++ /dev/null @@ -1,164 +0,0 @@ -Issues fixed in 2.0.1 : - - - All: CloudStorageAccount.*Parse methods throw an exception for "UseDevelopmentStorage=true" string. - - All: StorageErrorCodeStrings class is missing. - - Blobs: ICloudBlob interface does not have GetSharedAccessSignature method. - -Issues fixed in 2.0.2 : - - - All: CompletedSynchronously property returns inconsistent values on IAsyncResult objects returned by asynchronous methods and thus TaskFactory.FromAsync does not work properly. - - Tables: Public DynamicTableEntity constructors use DateTime even though the Timestamp property is of type DateTimeOffset. - - Tables: BeginSaveChangesWithRetries overload ignores the options argument. - -Issues fixed in 2.0.3 : - - - All (RT): General metadata correctness test fails when using the RT library to develop windows store apps. - - Queues: CloudQueueMessage.MaxNumberOfMessagesToPeek, CloudQueueMessage.MaxMessageSize and CloudQueueMessage.MaximumTimeToLive have disappeared from CloudQueueMessage. - - Queues: CloudQueue.BeginCreateIfNotExists and CloudQueue.BeginDeleteIfExists methods expect valid options argument. - - Tables: When one or more of the batches fails, but then succeeds on a retry, the "extra" TableResults of the failed transactions are also returned. - - Tables: TableQuery.GenerateFilterConditionForLong does not append 'L' at the end of the value and thus values larger than Int32.MaxValue cannot be used when filtering. - - Tables: TableEntity does not support serializing nullable values. - - Tables: CloudTable.EndListTablesSegmented method does not work correctly. - -Issues fixed in 2.0.4 : - - - All: Flush HttpWebRequest's request stream before calling BeginGetResponse. - - All: Support Null Retry Policies. - - Blobs: Continue ListContainers parsing if a container property is unknown. - - Queues (RT): DeleteMessageAsync(string messageId, string popReceipt) ignores the messageId and popReceipt. - - Tables: Add a TableConstant to define minimum DateTime supported. - - Tables: Correct count behavior with synchronous non segmented execution. - - Tables: Allow String.Empty in TableQuery Filters. - -Issues fixed in 2.0.4.1 : - - - All: Updated Odata dependency to latest and also changed nuspec to allow any version >= 5.2.0. - -Issues fixed in 2.0.5 : - - - All: StorageException is serializable. Also, other useful objects for debugging (StorageExtendedErrorInformation and RequestResult) are also serializable. - - All: SharedAccessSignature helper uses culture invariant characteristics to calculate SAS. - - All: CloudStorageAccount can parse connection strings with extra blank values. - - All: OperationContext StartTime and EndTime are populated during execution. - - All: StorageCredentials.UpdateKey does not work on SAS/Anonymous credentials anymore. - - All: Metadata headers are sorted using en-US culture to prevent 403 errors in some cultures. - - All: Fixed issue where in some cases a sync method call could result in a 0 ms timeout being set on HttpWebRequest. - - Blobs: Snapshot time embedded in blob Uri is parsed in the constructor. - - Blobs: GetBlobReferenceFromServer works with blob Uri that contain a SAS token. - - Blobs: BlobWriteStream honors AccessCondition. - - Blobs: BlobWriteStream prevents using StoreBlobContentMD5 on existing page blobs. - - Blobs: ICloudBlob has OpenRead method. - - Blobs: Cloud*Blob.OpenRead can be used with snapshots. - - Blobs: AbortCopy does not throw an exception anymore when a copy is successfully aborted. - - Queues: Ability to recreate CloudQueueMessage with Message Id and Pop Receipt. - - Tables: Exceptions during TableBatchOperation parse the entity index from the server response. - - Tables: Floating-point number filter is generated using invariant culture. - -Issues fixed in 2.0.5.1 : - - - All: Make sure the response stream is drained to prevent socket exhaustion. - -Issues fixed in 2.0.6.0 : - - - All: Default RetryPolicy filters updated to not retry 100-407, 409-499, 501, and 505 - - All: Support for all flavors of SharedKey and SharedKeyLite message signing through AuthenticationScheme property on client classes. - - All: Unusable HttpWebRequestFactory and WebRequestExtensions are not public anymore - - All: TranslateFromExceptionMessage has been deprecated in Microsoft.WindowsAzure.Storage.dll and is now available only in Microsoft.WindowsAzure.Storage.WinMD - - All: StorageCredentials supports empty account keys. - - All: RequestResult deserialization does not fail when Content-MD5 is missing - - Blobs (RT): DownloadToStreamAsync and DownloadRangeToStreamAsync writes the entire data to the given stream before returning back to the caller. - - Blobs (RT): UploadFromStreamAsync commits the blob in a worker thread to unblock UI. - - Blobs: Blob stream now uses a GUID instead of a random number as block ID prefix to prevent collisions. - - Queues: Changed return type of CloudQueue.BeginSetMetadata(AsyncCallback, object) to ICancellableAsyncResult. - - Tables: Changed default message signing to SharedKey (except for Data Services). - - Tables: EntityProperty updated to set the IsNull value for properties correctly in the case when the user sets an EntityProperty value through its setter. - - Tables: EdmType for null values in EntityProperty is set correctly and does not default to string any more. - -Issues fixed in 2.0.6.1 : - - - Tables: Fix for Table Service layer to drain response stream - -Changes in 2.1.0 : - - - All: Changed User-Agent header value to include .NET CLR and OS versions - - All: Performance improvements across all services (major improvements detailed below). - - All: Added logging functionality for all operations. - - All: Added Task overloads for all asynchronous APIs. - - All: Listing methods provide a third overload for that accepts just prefix. - - All: Exposed header, query and generic constants as public to assist clients developing via the protocol layer. - - All: Buffers that would end up in Large Object Heap are avoided as much as possible. - - All: OperationContext.ClientRequestID is automatically set for each operation with a new GUID if the user does not provide one. - - All: StorageCredentials exposes a new UpdateSASToken method to allow users to update their SAS Token in place. - - All: StorageCredentials exposes a new UpdateKey overload that only requires key value. - - All: StorageCredentials exposes a new ExportBase64EncodedKey method that returns the key in Base64 encoding. - - All: .NET MD5 implementation is used by default, FISMA (Native) MD5 can be enabled by setting CloudStorageAccount.UseV1MD5 to false explicitly. - - All: Mark the assembly to allow partially trusted callers. - - All: Added EndpointSuffix to CloudStorageAccount. - - All: Delays between request are pre-empted when user cancels the operation. - - All: Fix to measure End-to-end timeouts more accurately. - - All: Types that contain disposable objects implement IDisposable. - - All: Synchronous APIs correctly timeout if network IO is pending. - - All: When a request times out, the StorageException object that was thrown will contain a TimeoutException as InnerException. - - All: Synchronous requests do not retry errors anymore that occur before sending the request. - - All: Wait handles used for asynchronous requests are unregistered properly for better GC. - - All: CloudStorageAccount.ToString can recreate the original connection string that was passed in to CloudStorageAccount.Parse. - - All: Expose IBufferManager on ServiceClients enabling users to provide a buffer pooling implementation. - - All: Abort a pending request if upload times out to prevent socket exhaustion - - All: Fixed a potential overflow in ExponentialRetry. - - All: Queue and Table SAS validation should not check for signed resource(sr). Tables should check the table name(tn). - - Blobs: ICloudBlob exposes new BeginOpenRead/EndOpenRead methods to asynchronously open a stream to read from the blob. - - Blobs: Cloud[Block|Page]Blob.OpenRead performs a service request. - - Blobs: Streams opened with OpenRead methods do not discard the cache anymore if seeked to a position within the cached range. - - Blobs: Streams opened with OpenRead methods provide true synchronous Read API. - - Blobs: Streams opened with OpenRead methods do not allow calling multiple BeginRead methods because the result is undefined. - - Blobs: ICloudBlob.StreamMinimumReadSizeInBytes can be set to any value larger than or equal to 16KB. - - Blobs: OpenWrite methods return CloudBlobStream instead of Stream. The CloudBlobStream type provides explicit commit and asynchronous flush functionality. - - Blobs: Parallel upload performance of streams opened with OpenWrite methods is improved considerably due to keeping number of active operations at a certain level. - - Blobs: ICloudBlob exposes new UploadFromStream overloads that accept a length parameter, allowing users to upload a portion of the stream. - - Blobs: CloudBlockBlob.UploadFromStream correctly updates the locally cached MD5. - - Blobs: CloudBlockBlob exposes new UploadFromFile, UploadFromByteArray, and UploadText methods. - - Blobs: CloudPageBlob exposes new UploadFromFile and UploadFromByteArray methods. - - Blobs: CloudBlockBlob exposes new DownloadToFile, DownloadToByteArray, DownloadRangeToByteArray, and DownloadText methods. - - Blobs: CloudPageBlob exposes new DownloadToFile, DownloadToByteArray, and DownloadRangeToByteArray methods. - - Blobs: Added support for page blob sequence numbers. - - Blobs: Added support for public access to container creation. - - Blobs: Cloud[Block|Page]Blob.Exists also updates properties. - - Blobs: Cloud[Block|Page]Blob.StartCopyFromBlob verifies the source URI to prevent a possible NullReferenceException. - - Blobs: ICloudBlob exposes new IsSnapshot and SnapshotQualifiedUri properties for easier handling of blob snapshots. - - Blobs: Blob downloads skip length validation if Content-Length header is not set. - - Blobs: BlobProperties constructor that takes another BlobProperties object correctly copies all properties. - - Blobs: Traversing to the parent container from a CloudBlobDirectory does not create a new CloudBlobContainer object. - - Blobs (RT): IRandomAccessStreamWithContentType returned by ICloudBlob.OpenReadAsync correctly implements CloneStream and Seek. - - Blobs (RT): OpenWriteAsync methods return ICloudBlobStream instead of IOutputStream. ICloudBlobStream type provides explicit commit functionality. - - Blobs (RT): ICloudBlobStream.FlushAsync no longer blocks. - - Queues: MaxResults argument in queue listing APIs is nullable. - - Queues: CloudQueue.EndBeginClear is deprecated. - - Queues: All queue APIs are correctly marked with DoesServiceRequest attribute. - - Queues: New CloudQueue.BeginDeleteMessage overloads with less arguments. - - Queues (RT): visibilityTimeout argument of CloudQueue.UpdateMessage is not nullable. - - Queues (RT): CloudQueueClient.ListQueuesSegmentedAsync takes a new argument of type QueueRequestOptions. - - Tables: Table Service Layer supports queries with LINQ. - - Tables: TableEntity derived classes now support compiled serializers to improve serialization performance. - - Tables: Table allows query execution with a resolver against non-generic query types (dynamic entity types). - - Tables: Added IgnorePropertyAttribute for TableEntities to allow individual properties on POCO objects to be ignored during serialization. - - Tables: If-Match condition for Delete/Replace/Merge operations will not be set if entity ETag is null. - - Tables: Executing a batch operation with no operations will throw an InvalidOperationException instead of an ArgumentOutOfRangeException. - - Tables: To support IQueryable projections the TableQuery class Generic type is no longer constrained with where T: ITableEntity, new(). For TableQueries not created with via the IQueryable these same effective constraints are validated at runtime. - - Tables: Performance improvement to reduce Activator.CreateInstance usage for entity instantiation. - - Tables: Exposed PropertyAsObject Property in EntityProperty as publicly readable. - - Tables: Exposed table serialialization logic. Allow users to persist and read back entities that don't derive from TableEntity using static methods(ReadUserObject and WriteUserObject). - - Tables: Exposed CreateEntityPropertyFromObject in EntityProperty so users can pass in a value and get the corresponding EntityProperty. - - Tables: Escape single quote in PartitionKey and RowKey correctly while generating URIs. - -Issues fixed in 2.1.0.2 : - - - Blobs: Streams opened by OpenRead do not throw NotSupportedException when Flush is called. - - Tables: Generic ExecuteQuery methods on CloudTable execute IQueryable queries correctly by generating the filter string. - -Issues fixed in 2.1.0.3 : - - - All: Registered wait handles are unregistered sooner for more efficient GC. - -Issues fixed in 2.1.0.4 : - - - Tables: Do not send the cast operator in the table query filter string. diff --git a/microsoft-azure-api/Services/Storage/issues.txt b/microsoft-azure-api/Services/Storage/issues.txt deleted file mode 100644 index 2c9c0fff0538d..0000000000000 --- a/microsoft-azure-api/Services/Storage/issues.txt +++ /dev/null @@ -1,3 +0,0 @@ -Known Issues: - - - Windows Phone: When a request times out or is cancelled by the user, the asynchronous method might not invoke the user specified callback. diff --git a/microsoft-azure-api/build.proj b/microsoft-azure-api/build.proj deleted file mode 100644 index c2d700d8361eb..0000000000000 --- a/microsoft-azure-api/build.proj +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libraries/nuget.targets b/nuget.targets similarity index 97% rename from libraries/nuget.targets rename to nuget.targets index 37e38f45e8ee7..f05877624e42a 100644 --- a/libraries/nuget.targets +++ b/nuget.targets @@ -93,8 +93,8 @@ - - + + diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/License-Stable.rtf b/packages/Microsoft.Bcl.Build.1.0.10/License-Stable.rtf similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/License-Stable.rtf rename to packages/Microsoft.Bcl.Build.1.0.10/License-Stable.rtf diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/Microsoft.Bcl.Build.1.0.10.nupkg b/packages/Microsoft.Bcl.Build.1.0.10/Microsoft.Bcl.Build.1.0.10.nupkg similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/Microsoft.Bcl.Build.1.0.10.nupkg rename to packages/Microsoft.Bcl.Build.1.0.10/Microsoft.Bcl.Build.1.0.10.nupkg diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/content/net40/_._ b/packages/Microsoft.Bcl.Build.1.0.10/content/net40/_._ similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/content/net40/_._ rename to packages/Microsoft.Bcl.Build.1.0.10/content/net40/_._ diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/content/netcore45/_._ b/packages/Microsoft.Bcl.Build.1.0.10/content/netcore45/_._ similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/content/netcore45/_._ rename to packages/Microsoft.Bcl.Build.1.0.10/content/netcore45/_._ diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/content/portable-net40+win8+sl4+wp71/_._ b/packages/Microsoft.Bcl.Build.1.0.10/content/portable-net40+win8+sl4+wp71/_._ similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/content/portable-net40+win8+sl4+wp71/_._ rename to packages/Microsoft.Bcl.Build.1.0.10/content/portable-net40+win8+sl4+wp71/_._ diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/content/sl4-windowsphone71/_._ b/packages/Microsoft.Bcl.Build.1.0.10/content/sl4-windowsphone71/_._ similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/content/sl4-windowsphone71/_._ rename to packages/Microsoft.Bcl.Build.1.0.10/content/sl4-windowsphone71/_._ diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/content/sl4/_._ b/packages/Microsoft.Bcl.Build.1.0.10/content/sl4/_._ similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/content/sl4/_._ rename to packages/Microsoft.Bcl.Build.1.0.10/content/sl4/_._ diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Install.ps1 b/packages/Microsoft.Bcl.Build.1.0.10/tools/Install.ps1 similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Install.ps1 rename to packages/Microsoft.Bcl.Build.1.0.10/tools/Install.ps1 diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.Tasks.dll b/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.Tasks.dll similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.Tasks.dll rename to packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.Tasks.dll diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.targets b/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.targets similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.targets rename to packages/Microsoft.Bcl.Build.1.0.10/tools/Microsoft.Bcl.Build.targets diff --git a/libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Uninstall.ps1 b/packages/Microsoft.Bcl.Build.1.0.10/tools/Uninstall.ps1 similarity index 100% rename from libraries/packages/Microsoft.Bcl.Build.1.0.10/tools/Uninstall.ps1 rename to packages/Microsoft.Bcl.Build.1.0.10/tools/Uninstall.ps1 diff --git a/packages/repositories.config b/packages/repositories.config new file mode 100644 index 0000000000000..26924161182c3 --- /dev/null +++ b/packages/repositories.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/services/storage/README.md b/services/storage/README.md new file mode 100644 index 0000000000000..43d68a6ee54ae --- /dev/null +++ b/services/storage/README.md @@ -0,0 +1,10 @@ +# Windows Azure Storage Service # + +## Latest v3 Release + +The sources for the Windows Azure Storage Client Library is available in the azure-storage-net repository at [https://github.com/WindowsAzure/azure-storage-net](https://github.com/WindowsAzure/azure-storage-net). + +### v2.0.1.4 Tag + +The latest version of the v2.1.x storage client library is available in the azure-sdk-for-net repo under the [`v2.1.0.4` tag](https://github.com/WindowsAzure/azure-sdk-for-net/releases/tag/v2.1.0.4). + diff --git a/libraries/src/Common.NetFramework/CertificateCloudCredentials.cs b/src/Common.NetFramework/CertificateCloudCredentials.cs similarity index 100% rename from libraries/src/Common.NetFramework/CertificateCloudCredentials.cs rename to src/Common.NetFramework/CertificateCloudCredentials.cs diff --git a/libraries/src/Common.NetFramework/Common.NetFramework.csproj b/src/Common.NetFramework/Common.NetFramework.csproj similarity index 100% rename from libraries/src/Common.NetFramework/Common.NetFramework.csproj rename to src/Common.NetFramework/Common.NetFramework.csproj diff --git a/libraries/src/Common.NetFramework/Internals/PlatformConfigurationHelper.cs b/src/Common.NetFramework/Internals/PlatformConfigurationHelper.cs similarity index 100% rename from libraries/src/Common.NetFramework/Internals/PlatformConfigurationHelper.cs rename to src/Common.NetFramework/Internals/PlatformConfigurationHelper.cs diff --git a/libraries/src/Common.NetFramework/Platform/CertificateCloudCredentialsProvider.cs b/src/Common.NetFramework/Platform/CertificateCloudCredentialsProvider.cs similarity index 100% rename from libraries/src/Common.NetFramework/Platform/CertificateCloudCredentialsProvider.cs rename to src/Common.NetFramework/Platform/CertificateCloudCredentialsProvider.cs diff --git a/libraries/src/Common.NetFramework/Platform/CloudConfigurationProvider.cs b/src/Common.NetFramework/Platform/CloudConfigurationProvider.cs similarity index 100% rename from libraries/src/Common.NetFramework/Platform/CloudConfigurationProvider.cs rename to src/Common.NetFramework/Platform/CloudConfigurationProvider.cs diff --git a/libraries/src/Common.NetFramework/Platform/CryptographyProvider.cs b/src/Common.NetFramework/Platform/CryptographyProvider.cs similarity index 100% rename from libraries/src/Common.NetFramework/Platform/CryptographyProvider.cs rename to src/Common.NetFramework/Platform/CryptographyProvider.cs diff --git a/libraries/src/Common.NetFramework/Platform/HttpTransportHandlerProvider.cs b/src/Common.NetFramework/Platform/HttpTransportHandlerProvider.cs similarity index 100% rename from libraries/src/Common.NetFramework/Platform/HttpTransportHandlerProvider.cs rename to src/Common.NetFramework/Platform/HttpTransportHandlerProvider.cs diff --git a/libraries/src/Common.NetFramework/Platform/ServiceRuntimeReference.cs b/src/Common.NetFramework/Platform/ServiceRuntimeReference.cs similarity index 100% rename from libraries/src/Common.NetFramework/Platform/ServiceRuntimeReference.cs rename to src/Common.NetFramework/Platform/ServiceRuntimeReference.cs diff --git a/libraries/src/Common.NetFramework/Properties/AssemblyInfo.cs b/src/Common.NetFramework/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Common.NetFramework/Properties/AssemblyInfo.cs rename to src/Common.NetFramework/Properties/AssemblyInfo.cs diff --git a/libraries/src/Common.NetFramework/Properties/Resources.Designer.cs b/src/Common.NetFramework/Properties/Resources.Designer.cs similarity index 100% rename from libraries/src/Common.NetFramework/Properties/Resources.Designer.cs rename to src/Common.NetFramework/Properties/Resources.Designer.cs diff --git a/libraries/src/Common.NetFramework/Properties/Resources.resx b/src/Common.NetFramework/Properties/Resources.resx similarity index 100% rename from libraries/src/Common.NetFramework/Properties/Resources.resx rename to src/Common.NetFramework/Properties/Resources.resx diff --git a/libraries/src/Common.NetFramework/packages.config b/src/Common.NetFramework/packages.config similarity index 100% rename from libraries/src/Common.NetFramework/packages.config rename to src/Common.NetFramework/packages.config diff --git a/libraries/src/Common.Test/Common.Test.csproj b/src/Common.Test/Common.Test.csproj similarity index 100% rename from libraries/src/Common.Test/Common.Test.csproj rename to src/Common.Test/Common.Test.csproj diff --git a/libraries/src/Common.Test/Properties/AssemblyInfo.cs b/src/Common.Test/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Common.Test/Properties/AssemblyInfo.cs rename to src/Common.Test/Properties/AssemblyInfo.cs diff --git a/libraries/src/Common.Test/Tracing/CloudTracingExtensionsTest.cs b/src/Common.Test/Tracing/CloudTracingExtensionsTest.cs similarity index 100% rename from libraries/src/Common.Test/Tracing/CloudTracingExtensionsTest.cs rename to src/Common.Test/Tracing/CloudTracingExtensionsTest.cs diff --git a/libraries/src/Common.Test/packages.config b/src/Common.Test/packages.config similarity index 100% rename from libraries/src/Common.Test/packages.config rename to src/Common.Test/packages.config diff --git a/libraries/src/Common.Tracing.Etw/CloudTracingEventSource.cs b/src/Common.Tracing.Etw/CloudTracingEventSource.cs similarity index 100% rename from libraries/src/Common.Tracing.Etw/CloudTracingEventSource.cs rename to src/Common.Tracing.Etw/CloudTracingEventSource.cs diff --git a/libraries/src/Common.Tracing.Etw/Common.Tracing.Etw.csproj b/src/Common.Tracing.Etw/Common.Tracing.Etw.csproj similarity index 100% rename from libraries/src/Common.Tracing.Etw/Common.Tracing.Etw.csproj rename to src/Common.Tracing.Etw/Common.Tracing.Etw.csproj diff --git a/libraries/src/Common.Tracing.Etw/EtwTracingInterceptor.cs b/src/Common.Tracing.Etw/EtwTracingInterceptor.cs similarity index 100% rename from libraries/src/Common.Tracing.Etw/EtwTracingInterceptor.cs rename to src/Common.Tracing.Etw/EtwTracingInterceptor.cs diff --git a/libraries/src/Common.Tracing.Etw/GlobalSuppressions.cs b/src/Common.Tracing.Etw/GlobalSuppressions.cs similarity index 100% rename from libraries/src/Common.Tracing.Etw/GlobalSuppressions.cs rename to src/Common.Tracing.Etw/GlobalSuppressions.cs diff --git a/libraries/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuget.proj b/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuget.proj similarity index 100% rename from libraries/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuget.proj rename to src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuget.proj diff --git a/libraries/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuspec b/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuspec similarity index 100% rename from libraries/src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuspec rename to src/Common.Tracing.Etw/Microsoft.WindowsAzure.Common.Tracing.Etw.nuspec diff --git a/libraries/src/Common.Tracing.Etw/Properties/AssemblyInfo.cs b/src/Common.Tracing.Etw/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Common.Tracing.Etw/Properties/AssemblyInfo.cs rename to src/Common.Tracing.Etw/Properties/AssemblyInfo.cs diff --git a/libraries/src/Common.Tracing.Etw/packages.config b/src/Common.Tracing.Etw/packages.config similarity index 100% rename from libraries/src/Common.Tracing.Etw/packages.config rename to src/Common.Tracing.Etw/packages.config diff --git a/libraries/src/Common.Tracing.Etw/readme.txt b/src/Common.Tracing.Etw/readme.txt similarity index 100% rename from libraries/src/Common.Tracing.Etw/readme.txt rename to src/Common.Tracing.Etw/readme.txt diff --git a/libraries/src/Common.Tracing.Test/Common.Tracing.Test.csproj b/src/Common.Tracing.Test/Common.Tracing.Test.csproj similarity index 95% rename from libraries/src/Common.Tracing.Test/Common.Tracing.Test.csproj rename to src/Common.Tracing.Test/Common.Tracing.Test.csproj index d039a6c1ffb1f..c9d9284ee1916 100644 --- a/libraries/src/Common.Tracing.Test/Common.Tracing.Test.csproj +++ b/src/Common.Tracing.Test/Common.Tracing.Test.csproj @@ -86,17 +86,10 @@ - + - \ No newline at end of file diff --git a/libraries/src/Common.Tracing.Test/Etw/EtwTracingInterceptorTest.cs b/src/Common.Tracing.Test/Etw/EtwTracingInterceptorTest.cs similarity index 100% rename from libraries/src/Common.Tracing.Test/Etw/EtwTracingInterceptorTest.cs rename to src/Common.Tracing.Test/Etw/EtwTracingInterceptorTest.cs diff --git a/libraries/src/Common.Tracing.Test/Properties/AssemblyInfo.cs b/src/Common.Tracing.Test/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Common.Tracing.Test/Properties/AssemblyInfo.cs rename to src/Common.Tracing.Test/Properties/AssemblyInfo.cs diff --git a/libraries/src/Common.Tracing.Test/packages.config b/src/Common.Tracing.Test/packages.config similarity index 100% rename from libraries/src/Common.Tracing.Test/packages.config rename to src/Common.Tracing.Test/packages.config diff --git a/libraries/src/Common/CloudClients.cs b/src/Common/CloudClients.cs similarity index 100% rename from libraries/src/Common/CloudClients.cs rename to src/Common/CloudClients.cs diff --git a/libraries/src/Common/CloudContext.cs b/src/Common/CloudContext.cs similarity index 100% rename from libraries/src/Common/CloudContext.cs rename to src/Common/CloudContext.cs diff --git a/libraries/src/Common/Common.csproj b/src/Common/Common.csproj similarity index 100% rename from libraries/src/Common/Common.csproj rename to src/Common/Common.csproj diff --git a/libraries/src/Common/Configuration/CloudConfiguration.cs b/src/Common/Configuration/CloudConfiguration.cs similarity index 100% rename from libraries/src/Common/Configuration/CloudConfiguration.cs rename to src/Common/Configuration/CloudConfiguration.cs diff --git a/libraries/src/Common/Configuration/ConnectionStringSettingsFormat.cs b/src/Common/Configuration/ConnectionStringSettingsFormat.cs similarity index 100% rename from libraries/src/Common/Configuration/ConnectionStringSettingsFormat.cs rename to src/Common/Configuration/ConnectionStringSettingsFormat.cs diff --git a/libraries/src/Common/Configuration/JsonSettingsFormat.cs b/src/Common/Configuration/JsonSettingsFormat.cs similarity index 100% rename from libraries/src/Common/Configuration/JsonSettingsFormat.cs rename to src/Common/Configuration/JsonSettingsFormat.cs diff --git a/libraries/src/Common/Credentials/CloudCredentials.cs b/src/Common/Credentials/CloudCredentials.cs similarity index 100% rename from libraries/src/Common/Credentials/CloudCredentials.cs rename to src/Common/Credentials/CloudCredentials.cs diff --git a/libraries/src/Common/Credentials/SubscriptionCloudCredentials.cs b/src/Common/Credentials/SubscriptionCloudCredentials.cs similarity index 100% rename from libraries/src/Common/Credentials/SubscriptionCloudCredentials.cs rename to src/Common/Credentials/SubscriptionCloudCredentials.cs diff --git a/libraries/src/Common/Exception/CloudException.cs b/src/Common/Exception/CloudException.cs similarity index 100% rename from libraries/src/Common/Exception/CloudException.cs rename to src/Common/Exception/CloudException.cs diff --git a/libraries/src/Common/Exception/CloudHttpErrorInfo.cs b/src/Common/Exception/CloudHttpErrorInfo.cs similarity index 100% rename from libraries/src/Common/Exception/CloudHttpErrorInfo.cs rename to src/Common/Exception/CloudHttpErrorInfo.cs diff --git a/libraries/src/Common/Exception/CloudHttpRequestErrorInfo.cs b/src/Common/Exception/CloudHttpRequestErrorInfo.cs similarity index 100% rename from libraries/src/Common/Exception/CloudHttpRequestErrorInfo.cs rename to src/Common/Exception/CloudHttpRequestErrorInfo.cs diff --git a/libraries/src/Common/Exception/CloudHttpResponseErrorInfo.cs b/src/Common/Exception/CloudHttpResponseErrorInfo.cs similarity index 100% rename from libraries/src/Common/Exception/CloudHttpResponseErrorInfo.cs rename to src/Common/Exception/CloudHttpResponseErrorInfo.cs diff --git a/libraries/src/Common/Handlers/ClientRequestTrackingHandler.cs b/src/Common/Handlers/ClientRequestTrackingHandler.cs similarity index 100% rename from libraries/src/Common/Handlers/ClientRequestTrackingHandler.cs rename to src/Common/Handlers/ClientRequestTrackingHandler.cs diff --git a/libraries/src/Common/Handlers/LinearRetryHandler.cs b/src/Common/Handlers/LinearRetryHandler.cs similarity index 100% rename from libraries/src/Common/Handlers/LinearRetryHandler.cs rename to src/Common/Handlers/LinearRetryHandler.cs diff --git a/libraries/src/Common/Handlers/RetryHandler.cs b/src/Common/Handlers/RetryHandler.cs similarity index 100% rename from libraries/src/Common/Handlers/RetryHandler.cs rename to src/Common/Handlers/RetryHandler.cs diff --git a/libraries/src/Common/Internals/CloudExtensions.cs b/src/Common/Internals/CloudExtensions.cs similarity index 100% rename from libraries/src/Common/Internals/CloudExtensions.cs rename to src/Common/Internals/CloudExtensions.cs diff --git a/libraries/src/Common/Internals/ConfigurationHelper.cs b/src/Common/Internals/ConfigurationHelper.cs similarity index 100% rename from libraries/src/Common/Internals/ConfigurationHelper.cs rename to src/Common/Internals/ConfigurationHelper.cs diff --git a/libraries/src/Common/Internals/ConnectionStringParser.cs b/src/Common/Internals/ConnectionStringParser.cs similarity index 100% rename from libraries/src/Common/Internals/ConnectionStringParser.cs rename to src/Common/Internals/ConnectionStringParser.cs diff --git a/libraries/src/Common/Internals/Cryptography.cs b/src/Common/Internals/Cryptography.cs similarity index 100% rename from libraries/src/Common/Internals/Cryptography.cs rename to src/Common/Internals/Cryptography.cs diff --git a/libraries/src/Common/Internals/DisposableReference.cs b/src/Common/Internals/DisposableReference.cs similarity index 100% rename from libraries/src/Common/Internals/DisposableReference.cs rename to src/Common/Internals/DisposableReference.cs diff --git a/libraries/src/Common/Internals/HttpExtensions.cs b/src/Common/Internals/HttpExtensions.cs similarity index 100% rename from libraries/src/Common/Internals/HttpExtensions.cs rename to src/Common/Internals/HttpExtensions.cs diff --git a/libraries/src/Common/Internals/ICloudSettingsFormat.cs b/src/Common/Internals/ICloudSettingsFormat.cs similarity index 100% rename from libraries/src/Common/Internals/ICloudSettingsFormat.cs rename to src/Common/Internals/ICloudSettingsFormat.cs diff --git a/libraries/src/Common/Internals/IndisposableDelegatingHandler.cs b/src/Common/Internals/IndisposableDelegatingHandler.cs similarity index 100% rename from libraries/src/Common/Internals/IndisposableDelegatingHandler.cs rename to src/Common/Internals/IndisposableDelegatingHandler.cs diff --git a/libraries/src/Common/Internals/PortablePlatformAbstraction.cs b/src/Common/Internals/PortablePlatformAbstraction.cs similarity index 100% rename from libraries/src/Common/Internals/PortablePlatformAbstraction.cs rename to src/Common/Internals/PortablePlatformAbstraction.cs diff --git a/libraries/src/Common/Internals/Tracing.cs b/src/Common/Internals/Tracing.cs similarity index 100% rename from libraries/src/Common/Internals/Tracing.cs rename to src/Common/Internals/Tracing.cs diff --git a/libraries/src/Common/Internals/TypeConversion.cs b/src/Common/Internals/TypeConversion.cs similarity index 100% rename from libraries/src/Common/Internals/TypeConversion.cs rename to src/Common/Internals/TypeConversion.cs diff --git a/libraries/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuget.proj b/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuget.proj similarity index 100% rename from libraries/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuget.proj rename to src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuget.proj diff --git a/libraries/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuspec b/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuspec similarity index 100% rename from libraries/src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuspec rename to src/Common/Microsoft.WindowsAzure.Common.Dependencies.nuspec diff --git a/libraries/src/Common/Microsoft.WindowsAzure.Common.nuget.proj b/src/Common/Microsoft.WindowsAzure.Common.nuget.proj similarity index 100% rename from libraries/src/Common/Microsoft.WindowsAzure.Common.nuget.proj rename to src/Common/Microsoft.WindowsAzure.Common.nuget.proj diff --git a/libraries/src/Common/Microsoft.WindowsAzure.Common.nuspec b/src/Common/Microsoft.WindowsAzure.Common.nuspec similarity index 100% rename from libraries/src/Common/Microsoft.WindowsAzure.Common.nuspec rename to src/Common/Microsoft.WindowsAzure.Common.nuspec diff --git a/libraries/src/Common/Models/OperationResponse.cs b/src/Common/Models/OperationResponse.cs similarity index 100% rename from libraries/src/Common/Models/OperationResponse.cs rename to src/Common/Models/OperationResponse.cs diff --git a/libraries/src/Common/Models/Patchable.cs b/src/Common/Models/Patchable.cs similarity index 100% rename from libraries/src/Common/Models/Patchable.cs rename to src/Common/Models/Patchable.cs diff --git a/libraries/src/Common/Platform/ICloudConfigurationProvider.cs b/src/Common/Platform/ICloudConfigurationProvider.cs similarity index 100% rename from libraries/src/Common/Platform/ICloudConfigurationProvider.cs rename to src/Common/Platform/ICloudConfigurationProvider.cs diff --git a/libraries/src/Common/Platform/ICloudCredentialsProvider.cs b/src/Common/Platform/ICloudCredentialsProvider.cs similarity index 100% rename from libraries/src/Common/Platform/ICloudCredentialsProvider.cs rename to src/Common/Platform/ICloudCredentialsProvider.cs diff --git a/libraries/src/Common/Platform/ICryptographyProvider.cs b/src/Common/Platform/ICryptographyProvider.cs similarity index 100% rename from libraries/src/Common/Platform/ICryptographyProvider.cs rename to src/Common/Platform/ICryptographyProvider.cs diff --git a/libraries/src/Common/Platform/IHttpTransportHandlerProvider.cs b/src/Common/Platform/IHttpTransportHandlerProvider.cs similarity index 100% rename from libraries/src/Common/Platform/IHttpTransportHandlerProvider.cs rename to src/Common/Platform/IHttpTransportHandlerProvider.cs diff --git a/libraries/src/Common/Properties/AssemblyInfo.cs b/src/Common/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Common/Properties/AssemblyInfo.cs rename to src/Common/Properties/AssemblyInfo.cs diff --git a/libraries/src/Common/Properties/Resources.Designer.cs b/src/Common/Properties/Resources.Designer.cs similarity index 100% rename from libraries/src/Common/Properties/Resources.Designer.cs rename to src/Common/Properties/Resources.Designer.cs diff --git a/libraries/src/Common/Properties/Resources.resx b/src/Common/Properties/Resources.resx similarity index 100% rename from libraries/src/Common/Properties/Resources.resx rename to src/Common/Properties/Resources.resx diff --git a/libraries/src/Common/ServiceClient.cs b/src/Common/ServiceClient.cs similarity index 100% rename from libraries/src/Common/ServiceClient.cs rename to src/Common/ServiceClient.cs diff --git a/libraries/src/Common/ServiceOperations.cs b/src/Common/ServiceOperations.cs similarity index 100% rename from libraries/src/Common/ServiceOperations.cs rename to src/Common/ServiceOperations.cs diff --git a/libraries/src/Common/Tracing/CloudTracing.cs b/src/Common/Tracing/CloudTracing.cs similarity index 100% rename from libraries/src/Common/Tracing/CloudTracing.cs rename to src/Common/Tracing/CloudTracing.cs diff --git a/libraries/src/Common/Tracing/CloudTracingExtensions.cs b/src/Common/Tracing/CloudTracingExtensions.cs similarity index 100% rename from libraries/src/Common/Tracing/CloudTracingExtensions.cs rename to src/Common/Tracing/CloudTracingExtensions.cs diff --git a/libraries/src/Common/Tracing/ICloudTracingInterceptor.cs b/src/Common/Tracing/ICloudTracingInterceptor.cs similarity index 100% rename from libraries/src/Common/Tracing/ICloudTracingInterceptor.cs rename to src/Common/Tracing/ICloudTracingInterceptor.cs diff --git a/libraries/src/Common/packages.config b/src/Common/packages.config similarity index 100% rename from libraries/src/Common/packages.config rename to src/Common/packages.config diff --git a/libraries/src/ComputeManagement/ComputeManagement.csproj b/src/ComputeManagement/ComputeManagement.csproj similarity index 100% rename from libraries/src/ComputeManagement/ComputeManagement.csproj rename to src/ComputeManagement/ComputeManagement.csproj diff --git a/libraries/src/ComputeManagement/ComputeManagementClient.Customization.cs b/src/ComputeManagement/ComputeManagementClient.Customization.cs similarity index 100% rename from libraries/src/ComputeManagement/ComputeManagementClient.Customization.cs rename to src/ComputeManagement/ComputeManagementClient.Customization.cs diff --git a/libraries/src/ComputeManagement/ComputeManagementClient.cs b/src/ComputeManagement/ComputeManagementClient.cs similarity index 100% rename from libraries/src/ComputeManagement/ComputeManagementClient.cs rename to src/ComputeManagement/ComputeManagementClient.cs diff --git a/libraries/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuget.proj b/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuget.proj similarity index 100% rename from libraries/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuget.proj rename to src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuget.proj diff --git a/libraries/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuspec b/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuspec similarity index 100% rename from libraries/src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuspec rename to src/ComputeManagement/Microsoft.WindowsAzure.Management.Compute.nuspec diff --git a/libraries/src/ComputeManagement/Properties/AssemblyInfo.cs b/src/ComputeManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/ComputeManagement/Properties/AssemblyInfo.cs rename to src/ComputeManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/ComputeManagement/packages.config b/src/ComputeManagement/packages.config similarity index 100% rename from libraries/src/ComputeManagement/packages.config rename to src/ComputeManagement/packages.config diff --git a/libraries/src/Configuration/AzureApplicationSettings.cs b/src/Configuration/AzureApplicationSettings.cs similarity index 100% rename from libraries/src/Configuration/AzureApplicationSettings.cs rename to src/Configuration/AzureApplicationSettings.cs diff --git a/libraries/src/Configuration/CloudConfigurationManager.cs b/src/Configuration/CloudConfigurationManager.cs similarity index 100% rename from libraries/src/Configuration/CloudConfigurationManager.cs rename to src/Configuration/CloudConfigurationManager.cs diff --git a/libraries/src/Configuration/Configuration.csproj b/src/Configuration/Configuration.csproj similarity index 100% rename from libraries/src/Configuration/Configuration.csproj rename to src/Configuration/Configuration.csproj diff --git a/libraries/src/Configuration/GlobalSuppressions.cs b/src/Configuration/GlobalSuppressions.cs similarity index 100% rename from libraries/src/Configuration/GlobalSuppressions.cs rename to src/Configuration/GlobalSuppressions.cs diff --git a/libraries/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuget.proj b/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuget.proj similarity index 100% rename from libraries/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuget.proj rename to src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuget.proj diff --git a/libraries/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuspec b/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuspec similarity index 100% rename from libraries/src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuspec rename to src/Configuration/Microsoft.WindowsAzure.ConfigurationManager.nuspec diff --git a/libraries/src/Configuration/NativeMethods.cs b/src/Configuration/NativeMethods.cs similarity index 100% rename from libraries/src/Configuration/NativeMethods.cs rename to src/Configuration/NativeMethods.cs diff --git a/libraries/src/Configuration/Properties/AssemblyInfo.cs b/src/Configuration/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Configuration/Properties/AssemblyInfo.cs rename to src/Configuration/Properties/AssemblyInfo.cs diff --git a/libraries/src/Configuration/Properties/Resources.Designer.cs b/src/Configuration/Properties/Resources.Designer.cs similarity index 100% rename from libraries/src/Configuration/Properties/Resources.Designer.cs rename to src/Configuration/Properties/Resources.Designer.cs diff --git a/libraries/src/Configuration/Properties/Resources.resx b/src/Configuration/Properties/Resources.resx similarity index 100% rename from libraries/src/Configuration/Properties/Resources.resx rename to src/Configuration/Properties/Resources.resx diff --git a/libraries/src/Development.snk b/src/Development.snk similarity index 100% rename from libraries/src/Development.snk rename to src/Development.snk diff --git a/libraries/src/MSSharedLibKey.snk b/src/MSSharedLibKey.snk similarity index 100% rename from libraries/src/MSSharedLibKey.snk rename to src/MSSharedLibKey.snk diff --git a/libraries/src/Management/Management.csproj b/src/Management/Management.csproj similarity index 100% rename from libraries/src/Management/Management.csproj rename to src/Management/Management.csproj diff --git a/libraries/src/Management/ManagementClient.Customization.cs b/src/Management/ManagementClient.Customization.cs similarity index 100% rename from libraries/src/Management/ManagementClient.Customization.cs rename to src/Management/ManagementClient.Customization.cs diff --git a/libraries/src/Management/ManagementClient.cs b/src/Management/ManagementClient.cs similarity index 100% rename from libraries/src/Management/ManagementClient.cs rename to src/Management/ManagementClient.cs diff --git a/libraries/src/Management/Microsoft.WindowsAzure.Management.nuget.proj b/src/Management/Microsoft.WindowsAzure.Management.nuget.proj similarity index 100% rename from libraries/src/Management/Microsoft.WindowsAzure.Management.nuget.proj rename to src/Management/Microsoft.WindowsAzure.Management.nuget.proj diff --git a/libraries/src/Management/Microsoft.WindowsAzure.Management.nuspec b/src/Management/Microsoft.WindowsAzure.Management.nuspec similarity index 100% rename from libraries/src/Management/Microsoft.WindowsAzure.Management.nuspec rename to src/Management/Microsoft.WindowsAzure.Management.nuspec diff --git a/libraries/src/Management/Properties/AssemblyInfo.cs b/src/Management/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Management/Properties/AssemblyInfo.cs rename to src/Management/Properties/AssemblyInfo.cs diff --git a/libraries/src/Management/packages.config b/src/Management/packages.config similarity index 100% rename from libraries/src/Management/packages.config rename to src/Management/packages.config diff --git a/libraries/src/Microsoft.WindowsAzure.Management.Libraries.nuget.proj b/src/Microsoft.WindowsAzure.Management.Libraries.nuget.proj similarity index 100% rename from libraries/src/Microsoft.WindowsAzure.Management.Libraries.nuget.proj rename to src/Microsoft.WindowsAzure.Management.Libraries.nuget.proj diff --git a/libraries/src/Microsoft.WindowsAzure.Management.Libraries.nuspec b/src/Microsoft.WindowsAzure.Management.Libraries.nuspec similarity index 100% rename from libraries/src/Microsoft.WindowsAzure.Management.Libraries.nuspec rename to src/Microsoft.WindowsAzure.Management.Libraries.nuspec diff --git a/libraries/src/Monitoring/AlertsClient.cs b/src/Monitoring/AlertsClient.cs similarity index 100% rename from libraries/src/Monitoring/AlertsClient.cs rename to src/Monitoring/AlertsClient.cs diff --git a/libraries/src/Monitoring/AutoscaleClient.cs b/src/Monitoring/AutoscaleClient.cs similarity index 100% rename from libraries/src/Monitoring/AutoscaleClient.cs rename to src/Monitoring/AutoscaleClient.cs diff --git a/libraries/src/Monitoring/MetricClient.Customization.cs b/src/Monitoring/MetricClient.Customization.cs similarity index 100% rename from libraries/src/Monitoring/MetricClient.Customization.cs rename to src/Monitoring/MetricClient.Customization.cs diff --git a/libraries/src/Monitoring/MetricsClient.cs b/src/Monitoring/MetricsClient.cs similarity index 100% rename from libraries/src/Monitoring/MetricsClient.cs rename to src/Monitoring/MetricsClient.cs diff --git a/libraries/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuget.proj b/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuget.proj similarity index 100% rename from libraries/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuget.proj rename to src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuget.proj diff --git a/libraries/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuspec b/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuspec similarity index 100% rename from libraries/src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuspec rename to src/Monitoring/Microsoft.WindowsAzure.Management.Monitoring.nuspec diff --git a/libraries/src/Monitoring/Monitoring.csproj b/src/Monitoring/Monitoring.csproj similarity index 100% rename from libraries/src/Monitoring/Monitoring.csproj rename to src/Monitoring/Monitoring.csproj diff --git a/libraries/src/Monitoring/Properties/AssemblyInfo.cs b/src/Monitoring/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/Monitoring/Properties/AssemblyInfo.cs rename to src/Monitoring/Properties/AssemblyInfo.cs diff --git a/libraries/src/Monitoring/Utilities/AutoscaleMetricSourceBuilder.cs b/src/Monitoring/Utilities/AutoscaleMetricSourceBuilder.cs similarity index 100% rename from libraries/src/Monitoring/Utilities/AutoscaleMetricSourceBuilder.cs rename to src/Monitoring/Utilities/AutoscaleMetricSourceBuilder.cs diff --git a/libraries/src/Monitoring/Utilities/AutoscaleResourceIdBuilder.cs b/src/Monitoring/Utilities/AutoscaleResourceIdBuilder.cs similarity index 100% rename from libraries/src/Monitoring/Utilities/AutoscaleResourceIdBuilder.cs rename to src/Monitoring/Utilities/AutoscaleResourceIdBuilder.cs diff --git a/libraries/src/Monitoring/Utilities/Constants.cs b/src/Monitoring/Utilities/Constants.cs similarity index 100% rename from libraries/src/Monitoring/Utilities/Constants.cs rename to src/Monitoring/Utilities/Constants.cs diff --git a/libraries/src/Monitoring/Utilities/ResourceIdBuilder.cs b/src/Monitoring/Utilities/ResourceIdBuilder.cs similarity index 100% rename from libraries/src/Monitoring/Utilities/ResourceIdBuilder.cs rename to src/Monitoring/Utilities/ResourceIdBuilder.cs diff --git a/libraries/src/Monitoring/packages.config b/src/Monitoring/packages.config similarity index 100% rename from libraries/src/Monitoring/packages.config rename to src/Monitoring/packages.config diff --git a/libraries/src/NetworkManagement/Microsoft.WindowsAzure.Management.NetworkManagement.nuget.proj b/src/NetworkManagement/Microsoft.WindowsAzure.Management.NetworkManagement.nuget.proj similarity index 100% rename from libraries/src/NetworkManagement/Microsoft.WindowsAzure.Management.NetworkManagement.nuget.proj rename to src/NetworkManagement/Microsoft.WindowsAzure.Management.NetworkManagement.nuget.proj diff --git a/libraries/src/NetworkManagement/Microsoft.WindowsAzure.Management.VirtualNetworks.nuspec b/src/NetworkManagement/Microsoft.WindowsAzure.Management.VirtualNetworks.nuspec similarity index 100% rename from libraries/src/NetworkManagement/Microsoft.WindowsAzure.Management.VirtualNetworks.nuspec rename to src/NetworkManagement/Microsoft.WindowsAzure.Management.VirtualNetworks.nuspec diff --git a/libraries/src/NetworkManagement/NetworkManagement.csproj b/src/NetworkManagement/NetworkManagement.csproj similarity index 100% rename from libraries/src/NetworkManagement/NetworkManagement.csproj rename to src/NetworkManagement/NetworkManagement.csproj diff --git a/libraries/src/NetworkManagement/Properties/AssemblyInfo.cs b/src/NetworkManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/NetworkManagement/Properties/AssemblyInfo.cs rename to src/NetworkManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/NetworkManagement/VirtualNetworkManagementClient.Customizations.cs b/src/NetworkManagement/VirtualNetworkManagementClient.Customizations.cs similarity index 100% rename from libraries/src/NetworkManagement/VirtualNetworkManagementClient.Customizations.cs rename to src/NetworkManagement/VirtualNetworkManagementClient.Customizations.cs diff --git a/libraries/src/NetworkManagement/VirtualNetworkManagementClient.cs b/src/NetworkManagement/VirtualNetworkManagementClient.cs similarity index 100% rename from libraries/src/NetworkManagement/VirtualNetworkManagementClient.cs rename to src/NetworkManagement/VirtualNetworkManagementClient.cs diff --git a/libraries/src/NetworkManagement/packages.config b/src/NetworkManagement/packages.config similarity index 100% rename from libraries/src/NetworkManagement/packages.config rename to src/NetworkManagement/packages.config diff --git a/libraries/src/SchedulerManagement/CloudServiceManagementClient.Customization.cs b/src/SchedulerManagement/CloudServiceManagementClient.Customization.cs similarity index 100% rename from libraries/src/SchedulerManagement/CloudServiceManagementClient.Customization.cs rename to src/SchedulerManagement/CloudServiceManagementClient.Customization.cs diff --git a/libraries/src/SchedulerManagement/CloudServiceManagementClient.cs b/src/SchedulerManagement/CloudServiceManagementClient.cs similarity index 100% rename from libraries/src/SchedulerManagement/CloudServiceManagementClient.cs rename to src/SchedulerManagement/CloudServiceManagementClient.cs diff --git a/libraries/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuget.proj b/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuget.proj similarity index 100% rename from libraries/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuget.proj rename to src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuget.proj diff --git a/libraries/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuspec b/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuspec similarity index 100% rename from libraries/src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuspec rename to src/SchedulerManagement/Microsoft.WindowsAzure.Management.Scheduler.nuspec diff --git a/libraries/src/SchedulerManagement/Properties/AssemblyInfo.cs b/src/SchedulerManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/SchedulerManagement/Properties/AssemblyInfo.cs rename to src/SchedulerManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/SchedulerManagement/SchedulerClient.Customization.cs b/src/SchedulerManagement/SchedulerClient.Customization.cs similarity index 100% rename from libraries/src/SchedulerManagement/SchedulerClient.Customization.cs rename to src/SchedulerManagement/SchedulerClient.Customization.cs diff --git a/libraries/src/SchedulerManagement/SchedulerClient.cs b/src/SchedulerManagement/SchedulerClient.cs similarity index 100% rename from libraries/src/SchedulerManagement/SchedulerClient.cs rename to src/SchedulerManagement/SchedulerClient.cs diff --git a/libraries/src/SchedulerManagement/SchedulerManagement.csproj b/src/SchedulerManagement/SchedulerManagement.csproj similarity index 100% rename from libraries/src/SchedulerManagement/SchedulerManagement.csproj rename to src/SchedulerManagement/SchedulerManagement.csproj diff --git a/libraries/src/SchedulerManagement/SchedulerManagementClient.Customization.cs b/src/SchedulerManagement/SchedulerManagementClient.Customization.cs similarity index 100% rename from libraries/src/SchedulerManagement/SchedulerManagementClient.Customization.cs rename to src/SchedulerManagement/SchedulerManagementClient.Customization.cs diff --git a/libraries/src/SchedulerManagement/SchedulerManagementClient.cs b/src/SchedulerManagement/SchedulerManagementClient.cs similarity index 100% rename from libraries/src/SchedulerManagement/SchedulerManagementClient.cs rename to src/SchedulerManagement/SchedulerManagementClient.cs diff --git a/libraries/src/SchedulerManagement/packages.config b/src/SchedulerManagement/packages.config similarity index 100% rename from libraries/src/SchedulerManagement/packages.config rename to src/SchedulerManagement/packages.config diff --git a/libraries/src/ServiceBusManagement/Properties/AssemblyInfo.cs b/src/ServiceBusManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/ServiceBusManagement/Properties/AssemblyInfo.cs rename to src/ServiceBusManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/ServiceBusManagement/ServiceBus.Customizations.cs b/src/ServiceBusManagement/ServiceBus.Customizations.cs similarity index 100% rename from libraries/src/ServiceBusManagement/ServiceBus.Customizations.cs rename to src/ServiceBusManagement/ServiceBus.Customizations.cs diff --git a/libraries/src/ServiceBusManagement/ServiceBus.DiscoveryExtensions.cs b/src/ServiceBusManagement/ServiceBus.DiscoveryExtensions.cs similarity index 100% rename from libraries/src/ServiceBusManagement/ServiceBus.DiscoveryExtensions.cs rename to src/ServiceBusManagement/ServiceBus.DiscoveryExtensions.cs diff --git a/libraries/src/ServiceBusManagement/ServiceBusManagement.csproj b/src/ServiceBusManagement/ServiceBusManagement.csproj similarity index 100% rename from libraries/src/ServiceBusManagement/ServiceBusManagement.csproj rename to src/ServiceBusManagement/ServiceBusManagement.csproj diff --git a/libraries/src/ServiceBusManagement/ServiceBusManagementClient.cs b/src/ServiceBusManagement/ServiceBusManagementClient.cs similarity index 100% rename from libraries/src/ServiceBusManagement/ServiceBusManagementClient.cs rename to src/ServiceBusManagement/ServiceBusManagementClient.cs diff --git a/libraries/src/ServiceBusManagement/packages.config b/src/ServiceBusManagement/packages.config similarity index 100% rename from libraries/src/ServiceBusManagement/packages.config rename to src/ServiceBusManagement/packages.config diff --git a/libraries/src/SqlManagement/Properties/AssemblyInfo.cs b/src/SqlManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/SqlManagement/Properties/AssemblyInfo.cs rename to src/SqlManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/SqlManagement/Sql.Customizations.cs b/src/SqlManagement/Sql.Customizations.cs similarity index 100% rename from libraries/src/SqlManagement/Sql.Customizations.cs rename to src/SqlManagement/Sql.Customizations.cs diff --git a/libraries/src/SqlManagement/Sql.DiscoveryExtensions.cs b/src/SqlManagement/Sql.DiscoveryExtensions.cs similarity index 100% rename from libraries/src/SqlManagement/Sql.DiscoveryExtensions.cs rename to src/SqlManagement/Sql.DiscoveryExtensions.cs diff --git a/libraries/src/SqlManagement/SqlManagement.csproj b/src/SqlManagement/SqlManagement.csproj similarity index 100% rename from libraries/src/SqlManagement/SqlManagement.csproj rename to src/SqlManagement/SqlManagement.csproj diff --git a/libraries/src/SqlManagement/SqlManagementClient.cs b/src/SqlManagement/SqlManagementClient.cs similarity index 100% rename from libraries/src/SqlManagement/SqlManagementClient.cs rename to src/SqlManagement/SqlManagementClient.cs diff --git a/libraries/src/SqlManagement/packages.config b/src/SqlManagement/packages.config similarity index 100% rename from libraries/src/SqlManagement/packages.config rename to src/SqlManagement/packages.config diff --git a/libraries/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuget.proj b/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuget.proj similarity index 100% rename from libraries/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuget.proj rename to src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuget.proj diff --git a/libraries/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuspec b/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuspec similarity index 100% rename from libraries/src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuspec rename to src/StorageManagement/Microsoft.WindowsAzure.Management.Storage.nuspec diff --git a/libraries/src/StorageManagement/Properties/AssemblyInfo.cs b/src/StorageManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/StorageManagement/Properties/AssemblyInfo.cs rename to src/StorageManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/StorageManagement/StorageManagement.csproj b/src/StorageManagement/StorageManagement.csproj similarity index 100% rename from libraries/src/StorageManagement/StorageManagement.csproj rename to src/StorageManagement/StorageManagement.csproj diff --git a/libraries/src/StorageManagement/StorageManagementClient.Customization.cs b/src/StorageManagement/StorageManagementClient.Customization.cs similarity index 100% rename from libraries/src/StorageManagement/StorageManagementClient.Customization.cs rename to src/StorageManagement/StorageManagementClient.Customization.cs diff --git a/libraries/src/StorageManagement/StorageManagementClient.cs b/src/StorageManagement/StorageManagementClient.cs similarity index 100% rename from libraries/src/StorageManagement/StorageManagementClient.cs rename to src/StorageManagement/StorageManagementClient.cs diff --git a/libraries/src/StorageManagement/packages.config b/src/StorageManagement/packages.config similarity index 100% rename from libraries/src/StorageManagement/packages.config rename to src/StorageManagement/packages.config diff --git a/libraries/src/StoreManagement/Properties/AssemblyInfo.cs b/src/StoreManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/StoreManagement/Properties/AssemblyInfo.cs rename to src/StoreManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/StoreManagement/Store.Customizations.cs b/src/StoreManagement/Store.Customizations.cs similarity index 100% rename from libraries/src/StoreManagement/Store.Customizations.cs rename to src/StoreManagement/Store.Customizations.cs diff --git a/libraries/src/StoreManagement/Store.DiscoveryExtensions.cs b/src/StoreManagement/Store.DiscoveryExtensions.cs similarity index 100% rename from libraries/src/StoreManagement/Store.DiscoveryExtensions.cs rename to src/StoreManagement/Store.DiscoveryExtensions.cs diff --git a/libraries/src/StoreManagement/StoreManagement.csproj b/src/StoreManagement/StoreManagement.csproj similarity index 100% rename from libraries/src/StoreManagement/StoreManagement.csproj rename to src/StoreManagement/StoreManagement.csproj diff --git a/libraries/src/StoreManagement/StoreManagementClient.cs b/src/StoreManagement/StoreManagementClient.cs similarity index 100% rename from libraries/src/StoreManagement/StoreManagementClient.cs rename to src/StoreManagement/StoreManagementClient.cs diff --git a/libraries/src/StoreManagement/packages.config b/src/StoreManagement/packages.config similarity index 100% rename from libraries/src/StoreManagement/packages.config rename to src/StoreManagement/packages.config diff --git a/libraries/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuget.proj b/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuget.proj similarity index 100% rename from libraries/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuget.proj rename to src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuget.proj diff --git a/libraries/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuspec b/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuspec similarity index 100% rename from libraries/src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuspec rename to src/WebSiteManagement/Microsoft.WindowsAzure.Management.WebSites.nuspec diff --git a/libraries/src/WebSiteManagement/Properties/AssemblyInfo.cs b/src/WebSiteManagement/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/src/WebSiteManagement/Properties/AssemblyInfo.cs rename to src/WebSiteManagement/Properties/AssemblyInfo.cs diff --git a/libraries/src/WebSiteManagement/WebSiteCloudException.cs b/src/WebSiteManagement/WebSiteCloudException.cs similarity index 100% rename from libraries/src/WebSiteManagement/WebSiteCloudException.cs rename to src/WebSiteManagement/WebSiteCloudException.cs diff --git a/libraries/src/WebSiteManagement/WebSiteManagement.csproj b/src/WebSiteManagement/WebSiteManagement.csproj similarity index 100% rename from libraries/src/WebSiteManagement/WebSiteManagement.csproj rename to src/WebSiteManagement/WebSiteManagement.csproj diff --git a/libraries/src/WebSiteManagement/WebSiteManagementClient.Customization.cs b/src/WebSiteManagement/WebSiteManagementClient.Customization.cs similarity index 100% rename from libraries/src/WebSiteManagement/WebSiteManagementClient.Customization.cs rename to src/WebSiteManagement/WebSiteManagementClient.Customization.cs diff --git a/libraries/src/WebSiteManagement/WebSiteManagementClient.cs b/src/WebSiteManagement/WebSiteManagementClient.cs similarity index 100% rename from libraries/src/WebSiteManagement/WebSiteManagementClient.cs rename to src/WebSiteManagement/WebSiteManagementClient.cs diff --git a/libraries/src/WebSiteManagement/packages.config b/src/WebSiteManagement/packages.config similarity index 100% rename from libraries/src/WebSiteManagement/packages.config rename to src/WebSiteManagement/packages.config diff --git a/libraries/src/library.props b/src/library.props similarity index 100% rename from libraries/src/library.props rename to src/library.props diff --git a/libraries/src/library.targets b/src/library.targets similarity index 100% rename from libraries/src/library.targets rename to src/library.targets diff --git a/libraries/src/references.net40.props b/src/references.net40.props similarity index 100% rename from libraries/src/references.net40.props rename to src/references.net40.props diff --git a/libraries/src/references.net45.props b/src/references.net45.props similarity index 100% rename from libraries/src/references.net45.props rename to src/references.net45.props diff --git a/libraries/src/references.portable.props b/src/references.portable.props similarity index 100% rename from libraries/src/references.portable.props rename to src/references.portable.props diff --git a/libraries/src/references.props b/src/references.props similarity index 100% rename from libraries/src/references.props rename to src/references.props diff --git a/libraries/test/Microsoft.WindowsAzure.Configuration.Test/CloudConfigurationManagerTest.cs b/test/Microsoft.WindowsAzure.Configuration.Test/CloudConfigurationManagerTest.cs similarity index 100% rename from libraries/test/Microsoft.WindowsAzure.Configuration.Test/CloudConfigurationManagerTest.cs rename to test/Microsoft.WindowsAzure.Configuration.Test/CloudConfigurationManagerTest.cs diff --git a/libraries/test/Microsoft.WindowsAzure.Configuration.Test/Microsoft.WindowsAzure.Configuration.Test.csproj b/test/Microsoft.WindowsAzure.Configuration.Test/Microsoft.WindowsAzure.Configuration.Test.csproj similarity index 100% rename from libraries/test/Microsoft.WindowsAzure.Configuration.Test/Microsoft.WindowsAzure.Configuration.Test.csproj rename to test/Microsoft.WindowsAzure.Configuration.Test/Microsoft.WindowsAzure.Configuration.Test.csproj diff --git a/libraries/test/Microsoft.WindowsAzure.Configuration.Test/Properties/AssemblyInfo.cs b/test/Microsoft.WindowsAzure.Configuration.Test/Properties/AssemblyInfo.cs similarity index 100% rename from libraries/test/Microsoft.WindowsAzure.Configuration.Test/Properties/AssemblyInfo.cs rename to test/Microsoft.WindowsAzure.Configuration.Test/Properties/AssemblyInfo.cs