/* * BlobRoot = blob root name * BlobDirectoryReference = "directory name" * BlockBlobRef = "File name" * */ private void DownloadFileFromBlob(string BlobRoot, string BlobDirectoryReference, string BlockBlobRef, string LocalFileName) { try { if (!AZStorage.CloudStorageAccount.TryParse(ConfigurationManager.ConnectionStrings["AzureBlobStorageConfigConnection"].ConnectionString, out AZStorage.CloudStorageAccount StorageAccountAZ)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } AZBlob.CloudBlobClient ClientBlob = AZBlob.BlobAccountExtensions.CreateCloudBlobClient(StorageAccountAZ); var container = ClientBlob.GetContainerReference(BlobRoot); container.CreateIfNotExists(); AZBlob.CloudBlobDirectory directory = container.GetDirectoryReference(BlobDirectoryReference); AZBlob.CloudBlockBlob BlobBlock = directory.GetBlockBlobReference(BlockBlobRef); BlobBlock.DownloadToFile(LocalFileName, FileMode.OpenOrCreate); } catch (Exception ex) { throw new AzureTableBackupException(String.Format("Error downloading file '{0}'.", LocalFileName), ex); } finally { } }
public async void FileWriting(string message, CloudBlobContainer container) { //write exception to cloud storage string localPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string localFileName = "Exceptions" + Guid.NewGuid().ToString() + ".txt"; string sourceFile = Path.Combine(localPath, localFileName); File.WriteAllText(sourceFile, DateTime.Now.ToString() + " " + message); //write to cloud CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(localFileName); await cloudBlockBlob.UploadFromFileAsync(sourceFile); }
public static async Task <string> UploadFileToStorage(Stream fileStream, string fileName, TypeTable typeTable) { try { // Create storagecredentials object by reading the values from the configuration (appsettings.json) StorageCredentials storageCredentials = new StorageCredentials(accountName: CloudStorage.Instance.GetAccountCloudStorage(typeTable).AccountName, CloudStorage.Instance.GetAccountCloudStorage(typeTable).AccountKey); // Create cloudstorage account by passing the storagecredentials CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, true); // Create the blob client. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); // Get reference to the blob container by passing the name by reading the value from the configuration (appsettings.json) CloudBlobContainer container = blobClient.GetContainerReference(CloudStorage.Instance.GetAccountCloudStorage(typeTable).Container); container.CreateIfNotExists(); // Get the reference to the block blob from the container CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); string ext = System.IO.Path.GetExtension(fileName).ToLower(); blockBlob.Properties.ContentType = MimeTypes.GetMimeType(ext); // Upload the file await blockBlob.UploadFromStreamAsync(fileStream); string sas = blockBlob.GetSharedAccessSignature( new SharedAccessBlobPolicy() { Permissions = SharedAccessBlobPermissions.Read, SharedAccessStartTime = DateTime.Now.AddMinutes(-5), SharedAccessExpiryTime = DateTime.Now.AddYears(999) }); var url = blockBlob.Uri + sas; return(url); } catch (Exception e) { Console.WriteLine(e); throw; } }
/// <summary> /// Initializes a new instance of the BlobWriteStream class for a block blob. /// </summary> /// <param name="blockBlob">Blob reference to write to.</param> /// <param name="accessCondition">An object that represents the access conditions for the blob. If null, no condition is used.</param> /// <param name="options">An object that specifies additional options for the request.</param> /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param> internal BlobWriteStream(CloudBlockBlob blockBlob, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) : base(blockBlob, accessCondition, options, operationContext) { }
public async Task StoreBlobContentMD5TestAsync() { BlobRequestOptions optionsWithNoMD5 = new BlobRequestOptions() { StoreBlobContentMD5 = false, }; BlobRequestOptions optionsWithMD5 = new BlobRequestOptions() { StoreBlobContentMD5 = true, }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blob1 = container.GetBlockBlobReference("blob1"); using (Stream stream = new NonSeekableMemoryStream()) { await blob1.UploadFromStreamAsync(stream, null, optionsWithMD5, null); } await blob1.FetchAttributesAsync(); Assert.IsNotNull(blob1.Properties.ContentMD5); blob1 = container.GetBlockBlobReference("blob2"); using (Stream stream = new NonSeekableMemoryStream()) { await blob1.UploadFromStreamAsync(stream, null, optionsWithNoMD5, null); } await blob1.FetchAttributesAsync(); Assert.IsNull(blob1.Properties.ContentMD5); blob1 = container.GetBlockBlobReference("blob3"); using (Stream stream = new NonSeekableMemoryStream()) { await blob1.UploadFromStreamAsync(stream); } await blob1.FetchAttributesAsync(); Assert.IsNotNull(blob1.Properties.ContentMD5); CloudPageBlob blob2 = container.GetPageBlobReference("blob4"); blob2 = container.GetPageBlobReference("blob4"); using (Stream stream = new MemoryStream()) { await blob2.UploadFromStreamAsync(stream, null, optionsWithMD5, null); } await blob2.FetchAttributesAsync(); Assert.IsNotNull(blob2.Properties.ContentMD5); blob2 = container.GetPageBlobReference("blob5"); using (Stream stream = new MemoryStream()) { await blob2.UploadFromStreamAsync(stream, null, optionsWithNoMD5, null); } await blob2.FetchAttributesAsync(); Assert.IsNull(blob2.Properties.ContentMD5); blob2 = container.GetPageBlobReference("blob6"); using (Stream stream = new MemoryStream()) { await blob2.UploadFromStreamAsync(stream); } await blob2.FetchAttributesAsync(); Assert.IsNull(blob2.Properties.ContentMD5); } finally { container.DeleteIfExistsAsync().Wait(); } }
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, null, optionsWithMD5, null); } using (Stream stream = new MemoryStream()) { await blockBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, null); await blockBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, null)) { Stream blobStreamForRead = blobStream; int read; do { read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream blobStreamForRead = blobStream; 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, null, optionsWithMD5, opContext), opContext, "Downloading a blob with invalid MD5 should fail", HttpStatusCode.OK); await blockBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithMD5, null)) { Stream blobStreamForRead = blobStream; TestHelper.ExpectedException <IOException>( () => { int read; do { read = blobStreamForRead.Read(buffer, 0, buffer.Length); }while (read > 0); }, "Downloading a blob with invalid MD5 should fail"); } using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream blobStreamForRead = blobStream; 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, null, optionsWithMD5, null); } using (Stream stream = new MemoryStream()) { await pageBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, null); await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, null)) { Stream blobStreamForRead = blobStream; int read; do { read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream blobStreamForRead = blobStream; 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, null, optionsWithMD5, opContext), opContext, "Downloading a blob with invalid MD5 should fail", HttpStatusCode.OK); await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, null); using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithMD5, null)) { Stream blobStreamForRead = blobStream; TestHelper.ExpectedException <IOException>( () => { int read; do { read = blobStreamForRead.Read(buffer, 0, buffer.Length); }while (read > 0); }, "Downloading a blob with invalid MD5 should fail"); } using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, null)) { Stream blobStreamForRead = blobStream; int read; do { read = await blobStreamForRead.ReadAsync(buffer, 0, buffer.Length); }while (read > 0); } } } finally { container.DeleteIfExistsAsync().Wait(); } }
/// <summary> /// Create a blob file copy of the Azure Table specified. /// </summary> /// <param name="TableName">Name of Azure Table to backup.</param> /// <param name="BlobRoot">Name to use as blob root folder.</param> /// <param name="OutFileDirectory">Local directory (path) with authority to create/write a file.</param> /// <param name="Compress">True to compress the file.</param> /// <param name="Validate">True to validate the written record count matches what was queried.</param> /// <param name="RetentionDays">Process will age files in blob created more than x days ago.</param> /// <param name="TimeoutSeconds">Set timeout for table client.</param> /// <param name="filters">A list of Filter objects to be applied to table values extracted.</param> /// <returns>A string indicating the name of the blob file created as well as a count of how many files were aged.</returns> public string BackupTableToBlob(string TableName, string BlobRoot, string OutFileDirectory, bool Compress = false, bool Validate = false, int RetentionDays = 30, int TimeoutSeconds = 30, List <Filter> filters = default(List <Filter>)) { string OutFileName = ""; string OutFileNamePath = ""; int BackupsAged = 0; if (String.IsNullOrWhiteSpace(TableName)) { throw new ParameterSpecException("TableName is missing."); } if (String.IsNullOrWhiteSpace(BlobRoot)) { throw new ParameterSpecException("BlobRoot is missing."); } if (String.IsNullOrWhiteSpace(OutFileDirectory)) { throw new ParameterSpecException("OutFileDirectory is missing."); } try { OutFileName = this.BackupTableToFile(TableName, OutFileDirectory, Compress, Validate, TimeoutSeconds, filters); OutFileNamePath = Path.Combine(OutFileDirectory, OutFileName); if (!AZStorage.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureBlobConnectionSpec).Password, out AZStorage.CloudStorageAccount StorageAccountAZ)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } AZBlob.CloudBlobClient ClientBlob = AZBlob.BlobAccountExtensions.CreateCloudBlobClient(StorageAccountAZ); var container = ClientBlob.GetContainerReference(BlobRoot); container.CreateIfNotExists(); AZBlob.CloudBlobDirectory directory = container.GetDirectoryReference(BlobRoot.ToLower() + "-table-" + TableName.ToLower()); AZBlob.CloudBlockBlob BlobBlock = directory.GetBlockBlobReference(OutFileName); BlobBlock.UploadFromFile(OutFileNamePath); DateTimeOffset OffsetTimeNow = System.DateTimeOffset.Now; DateTimeOffset OffsetTimeRetain = System.DateTimeOffset.Now.AddDays(-1 * RetentionDays); //Cleanup old versions var BlobList = directory.ListBlobs().OfType <AZBlob.CloudBlockBlob>().ToList();; foreach (var blob in BlobList) { if (blob.Properties.Created < OffsetTimeRetain) { try { blob.Delete(); BackupsAged++; } catch (Exception ex) { throw new AgingException(String.Format("Error aging file '{0}'.", blob.Name), ex); } } } return(String.Format("Table '{0}' backed up as '{2}' under blob '{3}\\{4}'; {1} files aged.", TableName, BackupsAged, OutFileName, BlobRoot, directory.ToString())); } catch (ConnectionException cex) { throw cex; } catch (Exception ex) { throw new BackupFailedException(String.Format("Table '{0}' backup failed.", TableName), ex); } finally { if ((!String.IsNullOrEmpty(OutFileNamePath)) && (File.Exists(OutFileNamePath))) { try { File.Delete(OutFileNamePath); } catch (Exception ex) { throw new AzureTableBackupException(String.Format("Error cleaning up files '{0}'.", OutFileNamePath), ex); } } } }
public async Task UseTransactionalCRC64GetTestAsync() { BlobRequestOptions optionsWithNoCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = false } }; BlobRequestOptions optionsWithCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = true } }; byte[] buffer = GetRandomBuffer(3 * 1024 * 1024); Crc64Wrapper hasher = new Crc64Wrapper(); hasher.UpdateHash(buffer, 0, buffer.Length); string crc64 = hasher.ComputeHash(); string lastCheckCRC64 = null; OperationContext opContextWithCRC64Check = new OperationContext(); opContextWithCRC64Check.ResponseReceived += (_, args) => { if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; OperationContext opContextWithCRC64CheckAndInjectedFailure = new OperationContext(); opContextWithCRC64CheckAndInjectedFailure.ResponseReceived += (_, args) => { args.Response.Headers.Remove(Constants.HeaderConstants.ContentCrc64Header); args.Response.Headers.TryAddWithoutValidation(Constants.HeaderConstants.ContentCrc64Header, "dummy"); if (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckCRC64 = HttpResponseParsers.GetContentCRC64(args.Response); } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); using (Stream blobStream = await blockBlob.OpenWriteAsync()) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); //lastCheckCRC64 = null; //blockBlob.DownloadToStream(stream, null, optionsWithCRC64, opContextWithCRC64Check); //Assert.IsNotNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 2)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } using (Stream stream = new MemoryStream()) { lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithCRC64, opContextWithCRC64Check), "Page blob will not have CRC64 set by default; with UseTransactional, download should fail"); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithCRC64, opContextWithCRC64Check), "Downloading more than 4MB with transactional CRC64 should not be supported"); Assert.IsInstanceOfType(storageEx.InnerException, typeof(ArgumentOutOfRangeException)); lastCheckCRC64 = null; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckCRC64); } lastCheckCRC64 = "invalid_CRC64"; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckCRC64); } } } finally { await container.DeleteIfExistsAsync(); } }
public async Task UseTransactionalCRC64PutTestAsync() { BlobRequestOptions optionsWithNoCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = false } }; BlobRequestOptions optionsWithCRC64 = new BlobRequestOptions() { ChecksumOptions = new ChecksumOptions { UseTransactionalCRC64 = true } }; byte[] buffer = GetRandomBuffer(1024); Crc64Wrapper hasher = new Crc64Wrapper(); hasher.UpdateHash(buffer, 0, buffer.Length); string crc64 = hasher.ComputeHash(); string lastCheckCRC64 = null; int checkCount = 0; OperationContext opContextWithCRC64Check = new OperationContext(); opContextWithCRC64Check.SendingRequest += (_, args) => { if (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckCRC64 = HttpRequestParsers.GetContentCRC64(args.Request); checkCount++; } }; OperationContext opContextWithCRC64CheckAndInjectedFailure = new OperationContext(); opContextWithCRC64CheckAndInjectedFailure.SendingRequest += (_, args) => { args.Response.Headers.Remove(Constants.HeaderConstants.ContentCrc64Header); args.Request.Headers.TryAddWithoutValidation(Constants.HeaderConstants.ContentCrc64Header, "dummy"); if (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckCRC64 = HttpRequestParsers.GetContentCRC64(args.Request); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); List <string> blockIds = GetBlockIdList(3); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await blockBlob.PutBlockAsync(blockIds[0], blockData, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); blockData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[2], blockData, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); checkCount = 0; CloudAppendBlob appendBlob = container.GetAppendBlobReference("blob2"); await appendBlob.CreateOrReplaceAsync(); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); blockData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => appendBlob.AppendBlockAsync(blockData, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); await pageBlob.CreateAsync(buffer.Length); checkCount = 0; using (Stream pageData = new MemoryStream(buffer)) { lastCheckCRC64 = "invalid_CRC64"; await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.IsNull(lastCheckCRC64); lastCheckCRC64 = "invalid_CRC64"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); pageData.Seek(0, SeekOrigin.Begin); await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithCRC64, opContextWithCRC64CheckAndInjectedFailure), "Calculated CRC64 does not match existing property" ); lastCheckCRC64 = "invalid_CRC64"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, new Checksum(crc64 : crc64), null, optionsWithNoCRC64, opContextWithCRC64Check); Assert.AreEqual(crc64, lastCheckCRC64); } Assert.AreEqual(3, checkCount); lastCheckCRC64 = null; blockBlob = container.GetBlockBlobReference("blob4"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = "invalid_CRC64"; blockBlob = container.GetBlockBlobReference("blob5"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = null; pageBlob = container.GetPageBlobReference("blob6"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNotNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); lastCheckCRC64 = "invalid_CRC64"; pageBlob = container.GetPageBlobReference("blob7"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(buffer.Length * 3, null, optionsWithNoCRC64, opContextWithCRC64Check)) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } Assert.IsNull(lastCheckCRC64); Assert.AreEqual(1, checkCount); } finally { await container.DeleteIfExistsAsync(); } }
public async Task CloudBlobSnapshotAsync() { CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); MemoryStream originalData = new MemoryStream(GetRandomBuffer(1024)); CloudBlockBlob blockBlob = container.GetBlockBlobReference(BlobName); await blockBlob.UploadFromStreamAsync(originalData); CloudBlob blob = container.GetBlobReference(BlobName); await blob.FetchAttributesAsync(); 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); CloudBlob snapshot1 = await blob.SnapshotAsync(); 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")); CloudBlob snapshot2 = await blob.SnapshotAsync(); Assert.IsTrue(snapshot2.SnapshotTime.Value > snapshot1.SnapshotTime.Value); await snapshot1.FetchAttributesAsync(); await snapshot2.FetchAttributesAsync(); await blob.FetchAttributesAsync(); AssertAreEqual(snapshot1.Properties, blob.Properties); CloudBlob snapshot1Clone = new CloudBlob(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); // The query parser should not be case sensitive in detecting a snapshot in the query string CloudBlob snapshotParseVerifier = new CloudBlob(new Uri(blob.Uri + "?sNapshOt=" + snapshot1.SnapshotTime.Value.ToString("O")), blob.ServiceClient.Credentials); Assert.IsNotNull(snapshotParseVerifier.SnapshotTime, "Snapshot parse verifier did not successfully detect the snapshot time"); Assert.AreEqual(snapshot1.SnapshotTime.Value, snapshotParseVerifier.SnapshotTime.Value); CloudBlob snapshotCopy = container.GetBlobReference("blob2"); await snapshotCopy.StartCopyAsync(TestHelper.Defiddler(snapshot1.Uri)); await WaitForCopyAsync(snapshotCopy); Assert.AreEqual(CopyStatus.Success, snapshotCopy.CopyState.Status); using (Stream snapshotStream = (await snapshot1.OpenReadAsync())) { snapshotStream.Seek(0, SeekOrigin.End); TestHelper.AssertStreamsAreEqual(originalData, snapshotStream); } await blockBlob.PutBlockListAsync(new List <string>()); 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 <IListBlobItem> blobs = resultSegment.Results.ToList(); Assert.AreEqual(4, blobs.Count); AssertAreEqual(snapshot1, (CloudBlob)blobs[0]); AssertAreEqual(snapshot2, (CloudBlob)blobs[1]); AssertAreEqual(blob, (CloudBlob)blobs[2]); AssertAreEqual(snapshotCopy, (CloudBlob)blobs[3]); } finally { container.DeleteIfExistsAsync().Wait(); } }
public async Task UseTransactionalMD5PutTestAsync() { 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 (HttpRequestParsers.GetContentLength(args.Request) >= buffer.Length) { lastCheckMD5 = HttpRequestParsers.GetContentMD5(args.Request); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); List <string> blockIds = GetBlockIdList(3); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await blockBlob.PutBlockAsync(blockIds[0], blockData, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[1], blockData, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await blockBlob.PutBlockAsync(blockIds[2], blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); checkCount = 0; CloudAppendBlob appendBlob = container.GetAppendBlobReference("blob2"); await appendBlob.CreateOrReplaceAsync(); checkCount = 0; using (Stream blockData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; blockData.Seek(0, SeekOrigin.Begin); await appendBlob.AppendBlockAsync(blockData, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); await pageBlob.CreateAsync(buffer.Length); checkCount = 0; using (Stream pageData = new MemoryStream(buffer)) { lastCheckMD5 = "invalid_md5"; await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, null, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; pageData.Seek(0, SeekOrigin.Begin); await pageBlob.WritePagesAsync(pageData, 0, md5, null, optionsWithNoMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); } Assert.AreEqual(3, checkCount); lastCheckMD5 = null; blockBlob = container.GetBlockBlobReference("blob4"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(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("blob5"); checkCount = 0; using (Stream blobStream = await blockBlob.OpenWriteAsync(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("blob6"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(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("blob7"); checkCount = 0; using (Stream blobStream = await pageBlob.OpenWriteAsync(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 { await container.DeleteIfExistsAsync(); } }
/// <summary> /// Restore file created in blob storage by BackupAzureTables to the destination table name specified. /// Blob file will be downloaded to local storage before reading. If compressed, it will be decompressed on local storage before reading. /// </summary> /// <param name="DestinationTableName">Name of the Azure Table to restore to - may be different than name backed up originally.</param> /// <param name="OriginalTableName">Name of the Azure Table originally backed (required for determining blob directory to use)</param> /// <param name="BlobRoot">Name to use as blob root folder.</param> /// <param name="WorkingDirectory">Local directory (path) with authority to create/write a file.</param> /// <param name="BlobFileName">Name of the blob file to restore.</param> /// <param name="TimeoutSeconds">Set timeout for table client.</param> /// <returns>A string indicating the table restored and record count.</returns> public string RestoreTableFromBlob(string DestinationTableName, string OriginalTableName, string BlobRoot, string WorkingDirectory, string BlobFileName, int TimeoutSeconds = 30) { string result = "Error"; if (String.IsNullOrWhiteSpace(DestinationTableName)) { throw new ParameterSpecException("DestinationTableName is missing."); } if (String.IsNullOrWhiteSpace(OriginalTableName)) { throw new ParameterSpecException("OriginalTableName is missing."); } if (String.IsNullOrWhiteSpace(WorkingDirectory)) { throw new ParameterSpecException("WorkingDirectory is missing."); } if (!Directory.Exists(WorkingDirectory)) { throw new ParameterSpecException("WorkingDirectory does not exist."); } if (String.IsNullOrWhiteSpace(BlobFileName)) { throw new ParameterSpecException(String.Format("Invalid BlobFileName '{0}' specified.", BlobFileName)); } bool Decompress = BlobFileName.EndsWith(".7z"); if (String.IsNullOrWhiteSpace(BlobRoot)) { throw new ParameterSpecException(String.Format("Invalid BlobRoot '{0}' specified.", BlobRoot)); } if (Path.GetFullPath(WorkingDirectory) != WorkingDirectory) { throw new ParameterSpecException(String.Format("Invalid WorkingDirectory '{0}' specified.", WorkingDirectory)); } if (!AZStorage.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureBlobConnectionSpec).Password, out AZStorage.CloudStorageAccount StorageAccountAZ)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } try { AZBlob.CloudBlobClient ClientBlob = AZBlob.BlobAccountExtensions.CreateCloudBlobClient(StorageAccountAZ); var container = ClientBlob.GetContainerReference(BlobRoot); container.CreateIfNotExists(); AZBlob.CloudBlobDirectory directory = container.GetDirectoryReference(BlobRoot.ToLower() + "-table-" + OriginalTableName.ToLower()); string WorkingFileNamePath = Path.Combine(WorkingDirectory, BlobFileName); string WorkingFileNamePathCompressed = Path.Combine(WorkingDirectory, BlobFileName); /* * If file is compressed, WorkingFileNamePath will be set to .txt * If file is not compressed WorkingFileNamePathCompressed will be left as .txt */ if (Decompress) { WorkingFileNamePath = WorkingFileNamePath.Replace(".7z", ".txt"); } else { //WorkingFileNamePathCompressed = WorkingFileNamePathCompressed.Replace(".txt", ".7z"); } AZBlob.CloudBlockBlob BlobBlock = directory.GetBlockBlobReference(BlobFileName); BlobBlock.DownloadToFile(WorkingFileNamePathCompressed, FileMode.Create); //https://www.tutorialspoint.com/compressing-and-decompressing-files-using-gzip-format-in-chash if (Decompress) { FileStream FileToDeCompress = File.OpenRead(WorkingFileNamePathCompressed); using (FileStream OutFileDecompressed = new FileStream(WorkingFileNamePath, FileMode.Create)) { using (var zip = new GZipStream(FileToDeCompress, CompressionMode.Decompress, true)) { byte[] buffer = new byte[FileToDeCompress.Length]; while (true) { int count = zip.Read(buffer, 0, buffer.Length); if (count != 0) { OutFileDecompressed.Write(buffer, 0, count); } if (count != buffer.Length) { break; } } } FileToDeCompress.Close(); OutFileDecompressed.Close(); } } result = RestoreTableFromFile(DestinationTableName, WorkingFileNamePath, TimeoutSeconds); // Cleanup files if (File.Exists(WorkingFileNamePath)) { File.Delete(WorkingFileNamePath); } if (File.Exists(WorkingFileNamePathCompressed)) { File.Delete(WorkingFileNamePathCompressed); } } catch (ConnectionException cex) { throw cex; } catch (Exception ex) { throw new RestoreFailedException(String.Format("Table '{0}' restore failed.", DestinationTableName), ex); } finally { } return(result); }
/// <summary> /// Restore file from blob storage by BackupAzureTables to the destination table name specified. /// File will be read directly from blob storage. If the file is compressed, it will be decompressed to blob storage and then read. /// </summary> /// <param name="DestinationTableName">Name of the Azure Table to restore to - may be different than name backed up originally.</param> /// <param name="OriginalTableName">Name of the Azure Table originally backed (required for determining blob directory to use)</param> /// <param name="BlobRoot">Name to use as blob root folder.</param> /// <param name="BlobFileName">Name of the blob file to restore.</param> /// <param name="TimeoutSeconds">Set timeout for table client.</param> /// <returns>A string indicating the table restored and record count.</returns> public string RestoreTableFromBlobDirect(string DestinationTableName, string OriginalTableName, string BlobRoot, string BlobFileName, int TimeoutSeconds = 30) { if (String.IsNullOrWhiteSpace(DestinationTableName)) { throw new ParameterSpecException("DestinationTableName is missing."); } if (String.IsNullOrWhiteSpace(OriginalTableName)) { throw new ParameterSpecException("OriginalTableName is missing."); } if (String.IsNullOrWhiteSpace(BlobFileName)) { throw new ParameterSpecException(String.Format("Invalid BlobFileName '{0}' specified.", BlobFileName)); } bool Decompress = BlobFileName.EndsWith(".7z"); string TempFileName = String.Format("{0}.temp", BlobFileName); if (String.IsNullOrWhiteSpace(BlobRoot)) { throw new ParameterSpecException(String.Format("Invalid BlobRoot '{0}' specified.", BlobRoot)); } try { if (!CosmosTable.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureTableConnectionSpec).Password, out CosmosTable.CloudStorageAccount StorageAccount)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } if (!AZStorage.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureBlobConnectionSpec).Password, out AZStorage.CloudStorageAccount StorageAccountAZ)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } AZBlob.CloudBlobClient ClientBlob = AZBlob.BlobAccountExtensions.CreateCloudBlobClient(StorageAccountAZ); var container = ClientBlob.GetContainerReference(BlobRoot); container.CreateIfNotExists(); AZBlob.CloudBlobDirectory directory = container.GetDirectoryReference(BlobRoot.ToLower() + "-table-" + OriginalTableName.ToLower()); // If file is compressed, Decompress to a temp file in the blob if (Decompress) { AZBlob.CloudBlockBlob BlobBlockTemp = directory.GetBlockBlobReference(TempFileName); AZBlob.CloudBlockBlob BlobBlockRead = directory.GetBlockBlobReference(BlobFileName); using (AZBlob.CloudBlobStream decompressedStream = BlobBlockTemp.OpenWrite()) { using (Stream readstream = BlobBlockRead.OpenRead()) { using (var zip = new GZipStream(readstream, CompressionMode.Decompress, true)) { zip.CopyTo(decompressedStream); } } } BlobFileName = TempFileName; } AZBlob.CloudBlockBlob BlobBlock = directory.GetBlockBlobReference(BlobFileName); CosmosTable.CloudTableClient client = CosmosTable.CloudStorageAccountExtensions.CreateCloudTableClient(StorageAccount, new CosmosTable.TableClientConfiguration()); CosmosTable.CloudTable TableDest = client.GetTableReference(DestinationTableName); TableDest.ServiceClient.DefaultRequestOptions.ServerTimeout = new TimeSpan(0, 0, TimeoutSeconds); TableDest.CreateIfNotExists(); using (Stream BlobStream = BlobBlock.OpenRead()) { using (StreamReader InputFileStream = new StreamReader(BlobStream)) { string result = RestoreFromStream(InputFileStream, TableDest, DestinationTableName); if (Decompress) { AZBlob.CloudBlockBlob BlobBlockTemp = directory.GetBlockBlobReference(TempFileName); BlobBlockTemp.DeleteIfExists(); } return(result); } } } catch (ConnectionException cex) { throw cex; } catch (RestoreFailedException rex) { throw rex; } catch (Exception ex) { throw new RestoreFailedException(String.Format("Table '{0}' restore failed.", DestinationTableName), ex); } finally { } } // RestoreTableFromBlobDirect
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.DefaultRequestOptions.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 = 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.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } await bos.WriteAsync(buffer, 0, buffer.Length); await bos.CommitAsync(); } 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.DefaultRequestOptions.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.DefaultRequestOptions.MaximumExecutionTime.Value - (DateTime.Now - start)).TotalMilliseconds; if (msRemaining > 0) { await Task.Delay(msRemaining); } await bos.WriteAsync(buffer, 0, buffer.Length); await bos.CommitAsync(); } 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.DefaultRequestOptions.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.DefaultRequestOptions.MaximumExecutionTime = null; container.DeleteIfExistsAsync().Wait(); } }
public async Task CloudBlobClientMaximumExecutionTimeoutAsync() { CloudBlobClient blobClient = GenerateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(Guid.NewGuid().ToString("N")); byte[] buffer = BlobTestBase.GetRandomBuffer(80 * 1024 * 1024); try { await container.CreateAsync(); blobClient.DefaultRequestOptions.MaximumExecutionTime = TimeSpan.FromSeconds(5); blobClient.DefaultRequestOptions.SingleBlobUploadThresholdInBytes = 2 * 1024 * 1024; CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); blockBlob.StreamWriteSizeInBytes = 1 * 1024 * 1024; using (MemoryStream ms = new MemoryStream(buffer)) { try { await blockBlob.UploadFromStreamAsync(ms); Assert.Fail(); } catch (AggregateException ex) { #if !FACADE_NETCORE Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.InnerException.Message).ExceptionInfo.Message); #else Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.InnerException.Message).Exception.Message); #endif } catch (TaskCanceledException) { } } CloudPageBlob pageBlob = container.GetPageBlobReference("blob2"); pageBlob.StreamWriteSizeInBytes = 1 * 1024 * 1024; using (MemoryStream ms = new MemoryStream(buffer)) { try { await pageBlob.UploadFromStreamAsync(ms); Assert.Fail(); } catch (AggregateException ex) { #if !FACADE_NETCORE Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.InnerException.Message).ExceptionInfo.Message); #else Assert.AreEqual("The client could not finish the operation within specified timeout.", RequestResult.TranslateFromExceptionMessage(ex.InnerException.Message).Exception.Message); #endif } catch (TaskCanceledException) { } } } finally { blobClient.DefaultRequestOptions.MaximumExecutionTime = null; container.DeleteIfExistsAsync().Wait(); } }
/// <summary> /// Backup table directly to Blob. /// /// </summary> /// <param name="TableName">Name of Azure Table to backup.</param> /// <param name="BlobRoot">Name to use as blob root folder.</param> /// <param name="Compress">True to compress the file.</param> /// <param name="RetentionDays">Process will age files in blob created more than x days ago.</param> /// <param name="TimeoutSeconds">Set timeout for table client.</param> /// <param name="filters">A list of Filter objects to be applied to table values extracted.</param> /// <returns>A string containing the name of the file created.</returns> public string BackupTableToBlobDirect(string TableName, string BlobRoot, bool Compress = false, int RetentionDays = 30, int TimeoutSeconds = 30, List <Filter> filters = default(List <Filter>)) { string OutFileName = ""; int RecordCount = 0; int BackupsAged = 0; if (String.IsNullOrWhiteSpace(TableName)) { throw new ParameterSpecException("TableName is missing."); } if (String.IsNullOrWhiteSpace(BlobRoot)) { throw new ParameterSpecException("BlobRoot is missing."); } try { if (Compress) { OutFileName = String.Format(TableName + "_Backup_" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt.7z"); } else { OutFileName = String.Format(TableName + "_Backup_" + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt"); } if (!CosmosTable.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureTableConnectionSpec).Password, out CosmosTable.CloudStorageAccount StorageAccount)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } if (!AZStorage.CloudStorageAccount.TryParse(new System.Net.NetworkCredential("", AzureBlobConnectionSpec).Password, out AZStorage.CloudStorageAccount StorageAccountAZ)) { throw new ConnectionException("Can not connect to CloudStorage Account. Verify connection string."); } AZBlob.CloudBlobClient ClientBlob = AZBlob.BlobAccountExtensions.CreateCloudBlobClient(StorageAccountAZ); var container = ClientBlob.GetContainerReference(BlobRoot); container.CreateIfNotExists(); AZBlob.CloudBlobDirectory directory = container.GetDirectoryReference(BlobRoot.ToLower() + "-table-" + TableName.ToLower()); AZBlob.CloudBlockBlob BlobBlock = directory.GetBlockBlobReference(OutFileName); // start upload from stream, iterate through table, possible inline compress try { CosmosTable.CloudTableClient client = CosmosTable.CloudStorageAccountExtensions.CreateCloudTableClient(StorageAccount, new CosmosTable.TableClientConfiguration()); CosmosTable.CloudTable table = client.GetTableReference(TableName); table.ServiceClient.DefaultRequestOptions.ServerTimeout = new TimeSpan(0, 0, TimeoutSeconds); CosmosTable.TableContinuationToken token = null; var entities = new List <CosmosTable.DynamicTableEntity>(); var entitiesSerialized = new List <string>(); DynamicTableEntityJsonSerializer serializer = new DynamicTableEntityJsonSerializer(); TableSpec TableSpecStart = new TableSpec(TableName); var NewLineAsBytes = Encoding.UTF8.GetBytes("\n"); var tempTableSpecStart = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(TableSpecStart)); AZBlob.CloudBlobStream bs2 = BlobBlock.OpenWrite(); Stream bs = BlobBlock.OpenWrite(); if (Compress) { bs = new GZipStream(bs2, CompressionMode.Compress); } else { bs = bs2; } bs.Write(tempTableSpecStart, 0, tempTableSpecStart.Length); bs.Flush(); bs.Write(NewLineAsBytes, 0, NewLineAsBytes.Length); bs.Flush(); CosmosTable.TableQuery <CosmosTable.DynamicTableEntity> tq; if (default(List <Filter>) == filters) { tq = new CosmosTable.TableQuery <CosmosTable.DynamicTableEntity>(); } else { tq = new CosmosTable.TableQuery <CosmosTable.DynamicTableEntity>().Where(Filter.BuildFilterSpec(filters)); } do { var queryResult = table.ExecuteQuerySegmented(tq, token); foreach (CosmosTable.DynamicTableEntity dte in queryResult.Results) { var tempDTE = Encoding.UTF8.GetBytes(serializer.Serialize(dte)); bs.Write(tempDTE, 0, tempDTE.Length); bs.Flush(); bs.Write(NewLineAsBytes, 0, NewLineAsBytes.Length); bs.Flush(); RecordCount++; } token = queryResult.ContinuationToken; } while (token != null); TableSpec TableSpecEnd = new TableSpec(TableName, RecordCount); var tempTableSpecEnd = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(TableSpecEnd)); bs.Write(tempTableSpecEnd, 0, tempTableSpecEnd.Length); bs.Flush(); bs.Write(NewLineAsBytes, 0, NewLineAsBytes.Length); bs.Flush(); bs.Close(); } catch (Exception ex) { throw new BackupFailedException(String.Format("Table '{0}' backup failed.", TableName), ex); } DateTimeOffset OffsetTimeNow = System.DateTimeOffset.Now; DateTimeOffset OffsetTimeRetain = System.DateTimeOffset.Now.AddDays(-1 * RetentionDays); //Cleanup old versions var BlobList = directory.ListBlobs().OfType <AZBlob.CloudBlockBlob>().ToList();; foreach (var blob in BlobList) { if (blob.Properties.Created < OffsetTimeRetain) { try { blob.Delete(); BackupsAged++; } catch (Exception ex) { throw new AgingException(String.Format("Error aging file '{0}'.", blob.Name), ex); } } } return(String.Format("Table '{0}' backed up as '{2}' under blob '{3}\\{4}'; {1} files aged.", TableName, BackupsAged, OutFileName, BlobRoot, directory.ToString())); } catch (ConnectionException cex) { throw cex; } catch (Exception ex) { throw new BackupFailedException(String.Format("Table '{0}' backup failed.", TableName), ex); } finally { } } // BackupTableToBlobDirect
public async Task UseTransactionalMD5GetTestAsync() { 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 (long.Parse(HttpResponseParsers.GetContentLength(args.Response)) >= buffer.Length) { lastCheckMD5 = HttpResponseParsers.GetContentMD5(args.Response); checkCount++; } }; CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1"); using (Stream blobStream = await blockBlob.OpenWriteAsync()) { blobStream.Write(buffer, 0, buffer.Length); blobStream.Write(buffer, 0, buffer.Length); } checkCount = 0; using (Stream stream = new MemoryStream()) { lastCheckMD5 = null; await blockBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNotNull(lastCheckMD5); lastCheckMD5 = null; await blockBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check); Assert.IsNotNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; await blockBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => blockBlob.DownloadRangeToStreamAsync(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 = await blockBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckMD5); } lastCheckMD5 = "invalid_md5"; using (Stream blobStream = await blockBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckMD5); } } Assert.AreEqual(9, checkCount); CloudPageBlob pageBlob = container.GetPageBlobReference("blob3"); using (Stream blobStream = await pageBlob.OpenWriteAsync(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"; await pageBlob.DownloadToStreamAsync(stream, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); StorageException storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadToStreamAsync(stream, null, optionsWithMD5, opContextWithMD5Check), "Page blob will not have MD5 set by default; with UseTransactional, download should fail"); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, buffer.Length, buffer.Length, null, optionsWithMD5, opContextWithMD5Check); Assert.AreEqual(md5, lastCheckMD5); lastCheckMD5 = "invalid_md5"; await pageBlob.DownloadRangeToStreamAsync(stream, 1024, 4 * 1024 * 1024 + 1, null, optionsWithNoMD5, opContextWithMD5Check); Assert.IsNull(lastCheckMD5); storageEx = await TestHelper.ExpectedExceptionAsync <StorageException>( () => pageBlob.DownloadRangeToStreamAsync(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 = await pageBlob.OpenReadAsync(null, optionsWithMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNotNull(lastCheckMD5); } lastCheckMD5 = "invalid_md5"; using (Stream blobStream = await pageBlob.OpenReadAsync(null, optionsWithNoMD5, opContextWithMD5Check)) { blobStream.CopyTo(stream); Assert.IsNull(lastCheckMD5); } } Assert.AreEqual(9, checkCount); } finally { await container.DeleteIfExistsAsync(); } }
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 <string>()); CloudPageBlob pageBlob = container.GetPageBlobReference("pb"); await pageBlob.CreateAsync(0); CloudAppendBlob appendBlob = container.GetAppendBlobReference("ab"); await appendBlob.CreateOrReplaceAsync(); CloudBlobClient client; ICloudBlob blob; blob = await container.GetBlobReferenceFromServerAsync("bb"); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.Equals(blockBlob.StorageUri)); CloudBlockBlob blockBlobSnapshot = await((CloudBlockBlob)blob).CreateSnapshotAsync(); await blob.SetPropertiesAsync(); Uri blockBlobSnapshotUri = new Uri(blockBlobSnapshot.Uri.AbsoluteUri + "?snapshot=" + blockBlobSnapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSnapshotUri); AssertAreEqual(blockBlobSnapshot.Properties, blob.Properties); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(blockBlobSnapshot.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.GetBlobReferenceFromServerAsync("pb"); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.Equals(pageBlob.StorageUri)); CloudPageBlob pageBlobSnapshot = await((CloudPageBlob)blob).CreateSnapshotAsync(); await blob.SetPropertiesAsync(); Uri pageBlobSnapshotUri = new Uri(pageBlobSnapshot.Uri.AbsoluteUri + "?snapshot=" + pageBlobSnapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSnapshotUri); AssertAreEqual(pageBlobSnapshot.Properties, blob.Properties); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(pageBlobSnapshot.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.GetBlobReferenceFromServerAsync("ab"); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.Equals(appendBlob.StorageUri)); CloudAppendBlob appendBlobSnapshot = await((CloudAppendBlob)blob).CreateSnapshotAsync(); await blob.SetPropertiesAsync(); Uri appendBlobSnapshotUri = new Uri(appendBlobSnapshot.Uri.AbsoluteUri + "?snapshot=" + appendBlobSnapshot.SnapshotTime.Value.UtcDateTime.ToString("o")); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(appendBlobSnapshotUri); AssertAreEqual(appendBlobSnapshot.Properties, blob.Properties); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(appendBlobSnapshot.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlob.Uri); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(blockBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlob.Uri); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(pageBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(appendBlob.Uri); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(appendBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlob.StorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.Equals(blockBlob.StorageUri)); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlob.StorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.Equals(pageBlob.StorageUri)); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(appendBlob.StorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.Equals(appendBlob.StorageUri)); string blockBlobToken = blockBlob.GetSharedAccessSignature(policy); StorageCredentials blockBlobSAS = new StorageCredentials(blockBlobToken); Uri blockBlobSASUri = blockBlobSAS.TransformUri(blockBlob.Uri); StorageUri blockBlobSASStorageUri = blockBlobSAS.TransformUri(blockBlob.StorageUri); string appendBlobToken = appendBlob.GetSharedAccessSignature(policy); StorageCredentials appendBlobSAS = new StorageCredentials(appendBlobToken); Uri appendBlobSASUri = appendBlobSAS.TransformUri(appendBlob.Uri); StorageUri appendBlobSASStorageUri = appendBlobSAS.TransformUri(appendBlob.StorageUri); string pageBlobToken = pageBlob.GetSharedAccessSignature(policy); StorageCredentials pageBlobSAS = new StorageCredentials(pageBlobToken); Uri pageBlobSASUri = pageBlobSAS.TransformUri(pageBlob.Uri); StorageUri pageBlobSASStorageUri = pageBlobSAS.TransformUri(pageBlob.StorageUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(blockBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(pageBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(appendBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(appendBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(blockBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.Equals(blockBlob.StorageUri)); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(pageBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.Equals(pageBlob.StorageUri)); blob = await container.ServiceClient.GetBlobReferenceFromServerAsync(appendBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.Equals(appendBlob.StorageUri)); client = new CloudBlobClient(container.ServiceClient.BaseUri, blockBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(blockBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(blockBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); client = new CloudBlobClient(container.ServiceClient.BaseUri, pageBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(pageBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(pageBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); client = new CloudBlobClient(container.ServiceClient.BaseUri, appendBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(appendBlobSASUri); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.PrimaryUri.Equals(appendBlob.Uri)); Assert.IsNull(blob.StorageUri.SecondaryUri); client = new CloudBlobClient(container.ServiceClient.StorageUri, blockBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(blockBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudBlockBlob)); Assert.IsTrue(blob.StorageUri.Equals(blockBlob.StorageUri)); client = new CloudBlobClient(container.ServiceClient.StorageUri, pageBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(pageBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudPageBlob)); Assert.IsTrue(blob.StorageUri.Equals(pageBlob.StorageUri)); client = new CloudBlobClient(container.ServiceClient.StorageUri, appendBlobSAS); blob = await client.GetBlobReferenceFromServerAsync(appendBlobSASStorageUri, null, null, null); Assert.IsInstanceOfType(blob, typeof(CloudAppendBlob)); Assert.IsTrue(blob.StorageUri.Equals(appendBlob.StorageUri)); } finally { container.DeleteIfExistsAsync().Wait(); } }