98 Figure 3-11 is the diagram for the class layout.. As noted above, in order to make our components reusable, we define a base class called AzureStorageFacade, which encapsulates the ac
Trang 198
Figure 3-11 is the diagram for the class layout As noted above, in order to make our components reusable, we define a base class called AzureStorageFacade, which encapsulates the account
initialization function in the constructor We subclass three classes also using the facade design pattern
to wrap up all the interfaces used to access Azure basic storages, table, queue and blob, respectively These three subclasses are AzureStorage, TableStorage, and BlobStorage In this exercise we are going to use this base class to re-engineer the blob access classes from previous exercise and leave you to apply the first two classes to all existing exercises from previous chapters or use them in future development
Figure 3-11 Class diagram for large data I/O to cloud blob storage tools
Listing 3-15 is the implementation of the base class AzureStorageFacade There is only one member method Initialization() defined, which is used to retrieve the account information from the
configuration file
Listing 3-15 Implementation of the Base Class AzureStorageFacade
using System;
using System.Configuration;
namespace AzureForDotNetDevelopers.LargeDataToBlob
{
using Microsoft.ServiceHosting.ServiceRuntime;
using Microsoft.Samples.ServiceHosting.StorageClient;
Trang 299
public class AzureStorageFacade
{
protected StorageAccountInfo accountInformation;
protected int retry = 1;
protected int retryInterval = 1000;
public StorageAccountInfo StorageAccountInfo
{
get{ return accountInformation; }
}
public AzureStorageFacade()
{
InitializationStorages();
}
protected void InitializationStorages()
{
retry = Convert.ToInt32(ConfigurationManager.AppSettings["Retry"]);
retryInterval =
Convert.ToInt32(ConfigurationManager.AppSettings["RetryInterval"]);
accountInformation =
StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();
}
}
}
Listing 3-16 shows the implementation of the blob facade class, which encapsulates all blob storage access functions and attributes of blob storage needed for a client application in a more comprehensive manner than in the implementation in the previous exercise
Listing 3-16 Implementation of the BlobStorageFacade Class Derived from the AzureStorageFacade Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections.Specialized;
using System.Threading;
using System.IO;
namespace AzureForDotNetDevelopers.LargeDataToBlob.CloudStorage.BlobStorage
{
using Microsoft.ServiceHosting.ServiceRuntime;
using Microsoft.Samples.ServiceHosting.StorageClient;
using CSharpBuildingBlocks;
Trang 3100
public class BlobStorageFacade : AzureStorageFacade
{
static public long LARGE BLOB SIZE = 2 * 1024 * 1024;// 2 MB
protected BlobStorage blobStorage;
protected BlobContainer blobContainer;
protected string blobContainerName =
ConfigurationManager.AppSettings["BlobContainerName"];
protected NameValueCollection metadata = null;
protected Thread createBlobWorkerthread = null;
public BlobContents Contents { get; set; }
public BlobProperties Properties { get; set; }
public bool Overwrite { get; set; }
public BlobStorageFacade()
{
blobStorage = BlobStorage.Create( accountInformation);
blobStorage.RetryPolicy =
RetryPolicies.RetryN(retry, TimeSpan.FromMilliseconds(retryInterval)); blobContainer = blobStorage.GetBlobContainer( blobContainerName); }
public BlobStorageFacade(NameValueCollection metadata):this()
{
metadata = metadata;
blobContainer.CreateContainer( metadata, ContainerAccessControl.Private); }
public BlobStorageFacade(BlobContents blobContents,
BlobProperties blobProperties,
bool overwrite) : this(blobProperties.Metadata) {
Contents = blobContents;
Properties = blobProperties;
Overwrite = overwrite;
}
public BlobContainer BlobContainer
{
get { return blobContainer; }
}
public IEnumerable<BlobContainer> GetBlobContainers()
{
return blobStorage.ListBlobContainers();
}
public void CreateBlob()
{
blobContainer.CreateBlob(Properties,
Contents,
Trang 4101
Overwrite);
}
public void DeleteBlob()
{
if ( blobContainer.DoesBlobExist(Properties.Name))
{
blobContainer.DeleteBlob(Properties.Name);
}
}
}
}
As mentioned before, we use a background worker thread and ICommand design pattern in this
application The base class implementation for these two classes comes from my existing building block collection library The reference assemblies are called CSharpBuildingBlocks and
CSharpBuildingBlocks.QueuedBackgroundWorker These two assemblies come with the source code
download and will be used several places in other chapters
Listing 3-17 and Listing 3-18 are the implementation for CreateBlobStatus and DeleteBlobStatus A worker thread is created at the time a message arrives for either creating or deleting a blob request Two member functions are used to handle create or delete activities accordingly The algorithms for progress are different in these two classes
For blob creation, the percentage of the creation progress is determined by comparing the size of
the blob to be created against the actual size of the data that has been committed to cloud blob storage
No incremented progress can be reported to the client application, because the detailed information of a newly created or deleted blob will not be updated until the transactions have been committed on the
server
Listing 3-17 The CreateBlobStatus Class Derived from the BlobStorageAction Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections.Specialized;
using System.Threading;
namespace AzureForDotNetDevelopers.LargeDataToBlob.CloudStorage.BlobStorage
{
using Microsoft.ServiceHosting.ServiceRuntime;
using Microsoft.Samples.ServiceHosting.StorageClient;
using CSharpBuildingBlocks;
public class CreateBlobStatus : BlobStorageActionStatus, ICommand
{
public long CreateContentSize { get; set; }
public CreateBlobStatus(BlobContents blobContents,
BlobProperties blobProperties,
Trang 5102
bool overwrite)
: base(blobContents,
blobProperties,
overwrite)
{
}
public void Execute() {
try {
if ( blobStorageFacade.BlobContainer DoesBlobExist( blobStorageFacade.Properties.Name)) {
var blob = (from m in blobStorageFacade.BlobContainer.ListBlobs(string.Empty, false) where (m as BlobProperties).Name == blobStorageFacade.Properties.Name select m as BlobProperties).Single<BlobProperties>(); percentComplete = (float)(((blob as BlobProperties).ContentLength * 100.0) / (CreateContentSize * 1.0)); System.Diagnostics.Trace.WriteLine( string.Format( " -{0}:Execute, percentComplete = <{1}>", this.ToString(), percentComplete )
);
}
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine( string.Format( " -{0}:Execute,exception caught <{1}>", this.ToString(), ex.Message )
);
}
}
override protected void blobStorageWorkerThread(object paramters) {
try {