1. Trang chủ
  2. » Công Nghệ Thông Tin

Introducing Windows Azure- P25 pot

5 185 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 93 { return RoleStatus.Healthy; } private void Initialization() { if ( initialized) { return; } lock ( syncObj) { try { //Instatiate BlobStorage blobStorage = BlobStorage.Create(StorageAccountInfo .GetDefaultBlobStorageAccountFromConfiguration()); blobContainer = blobStorage.GetBlobContainer(WorkerRole.PAYLOAD BLOB CONTAINER NAME); // Make the container public so that we can hit the URLs from the web blobContainer.CreateContainer(new NameValueCollection(), ContainerAccessControl.Public); //Instatiate QueueStorage queueStorage = QueueStorage.Create(StorageAccountInfo .GetDefaultQueueStorageAccountFromConfiguration()); queueStorage.RetryPolicy = RetryPolicies.RetryN(3, TimeSpan.FromSeconds(5)); //Create a queue to listen blob create request message //and register the events MessageQueue requstQueue = queueStorage.GetQueue(PAYLOAD CREATE REQUEST QUEUE NAME); requstQueue.CreateQueue(); requstQueue.MessageReceived += new MessageReceivedEventHandler( OnCreateBlobMessageReceive); requstQueue.PollInterval = POLLING INTERVAL; requstQueue.StartReceiving(); //Create a queue without to register any event to send the blob created //message with blob name to the queue MessageQueue resultsQueue = queueStorage.GetQueue(PAYLOAD RESULTS QUEUE NAME); resultsQueue.CreateQueue(); //Create a queue to listen blob delete request message //and register the events MessageQueue deleteQueue = CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 94 queueStorage.GetQueue(PAYLOAD DELETE QUEUE NAME); deleteQueue.CreateQueue(); deleteQueue.MessageReceived += new MessageReceivedEventHandler( OnDeleteBlobMessageReceive); deleteQueue.PollInterval = POLLING INTERVAL; deleteQueue.StartReceiving(); initialized = true; } catch (Exception ex) { LogError( string.Format( " {0}: Initialization, exception caught : {1}", this.ToString(), ex.Message ) ); } initialized = true; } } private void CreateBlob(Message message) { lock ( syncObj) { string logMessage = string.Format( " {0}: OnMessageReceive, message = <{1}>", this.ToString(), message.ContentAsString() ); System.Diagnostics.Trace.WriteLine(logMessage); Log(logMessage); string blobName = string.Format("{0}{1}", message.Id, PAYLOAD BLOB SUFFIX); if (! blobContainer.DoesBlobExist(blobName)) { // Compose a unique blob name BlobProperties properties = new BlobProperties(blobName); // Create metadata to be associated with the blob NameValueCollection metadata = new NameValueCollection(); metadata["MediaID"] = message.Id; properties.Metadata = metadata; properties.ContentType = "text/xml"; CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 95 // Create the blob byte[] buffer = UTF8Encoding.UTF8.GetBytes( message.ContentAsString().Replace("\r\n", string.Empty) ); MemoryStream ms = new MemoryStream(buffer); BlobContents blobContents = new BlobContents(ms); blobContainer.CreateBlob(properties, blobContents, true); var blob = (from m in blobContainer.ListBlobs(string.Empty, false) where (m as BlobProperties).Name == blobName select m as BlobProperties).Single <BlobProperties>(); if (null != blob ) { MediaInfo mediaInfo = new MediaInfo( blobName, (blob as BlobProperties).Uri.ToString(), message.Id ); Message resultsMessage = CreateMediaInfoMessage(mediaInfo); MessageQueue queue = queueStorage.GetQueue(PAYLOAD RESULTS QUEUE NAME); queue.PutMessage(resultsMessage); } } queueStorage.GetQueue(PAYLOAD CREATE REQUEST QUEUE NAME) .DeleteMessage(message); } } private void OnCreateBlobMessageReceive(object sender, EventArgs args) { lock ( syncObj) { CreateBlob((args as MessageReceivedEventArgs).Message); } } private Message CreateMediaInfoMessage(MediaInfo info) { StringBuilder sb = Helper.XmlPersist(info, typeof(MediaInfo)); return new Message(UTF8Encoding.UTF8.GetBytes(sb.ToString())); } private void OnDeleteBlobMessageReceive(object sender, EventArgs args) { lock ( syncObj) { CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 96 Message message = (args as MessageReceivedEventArgs).Message; string blobName = message.ContentAsString(); Log( string.Format( " {0}:received delete blob request, blob name = <{1}>", this.ToString(), blobName ) ); if ( blobContainer.DoesBlobExist(blobName)) { Log( string.Format( " {0}:delete blob request, blob name = <{1}>", this.ToString(), blobName ) ); blobContainer.DeleteBlob(blobName); } queueStorage.GetQueue(PAYLOAD DELETE QUEUE NAME).DeleteMessage(message); ; } } } } Compiling the code and running the application, we get the same results with this new architecture design as Figure 3-8 shown in the last exercise. Through this exercise, we have actually built a template for a cloud application that can be used as a communication bus between the web roles and worker roles. This is the solution to decouple a web role from a worker role. Since a worker role cannot expose its end point, it cannot accept external HTTP requests. We can leverage the queue as the message bus to build the communication bridge between a web role and worker role. In fact Azure uses the same approach to decouple its front-end services to increase efficiency and performance. Implementing a Client Application to Access Cloud Blob Storage If we need to upload or delete a large amount of data from cloud blob storage in a client-side application, we should consider not only using an asynchronous approach to handle the task in a background thread, but also supporting manually interruption if something goes wrong, which may be caused by network failure or other reasons since Azure blob storage handles transactions on the server side, not on the client side. Under the hood, the SDK client wrapper dispatches the request by calling two different overloaded handler methods based upon the size of the data. If the data size is greater than 2 MB, the data will be processed through the large data upload hander from the Azure storage client. The Azure blob storage client may contact a group of connected servers in the cloud based upon the balance of the server load. CHAPTER 3 ■ WORKING WITH CLOUD QUEUE AND BLOB STORAGE 97 The contents will be split into numerous data blocks and spread to multiple servers. The Azure blob storage client will call a method to commit the transaction. If any process fails or an interruption occurs, the transaction will not be committed. This exercise provides a workaround to resolve uploading and downloading a large amount of blob data on the client side. This application may potentially be used as a utility tool for anyone who needs to transmit a large amount of data to a cloud blob. In this exercise we will walk you through creation of a Windows-based tool that can be used to upload and delete large amounts of data from cloud blob storage. ■ Note The code for this example is in the Exercise 3-4 bundle from the code download. There are two technologies for handling large amounts of data, especially data transmission over the network: • Asynchronous data transmission • Background worker item thread The .NET Framework provides extensive support for these two technologies, such as a thread pools and a background worker class. This exercise uses these two technologies in conjunction with other software design patterns, such as the command and facade design patterns to come up with a useful client-side tool to handle large data I/O to Azure blob storage. At the highest level, we define two modules: AzureStorageFacade and BlobStorageActionStatus. The responsibilities of these two classes are as follows. • AzureStorageFacade is an abstract base class that wraps the class of the Azure storage SDK client. The responsibility of the base class is to instantiate the Azure account object, including the authentication key information. We are going create two classes called BlobStorageFacade and TableStorageFacade that will inherit from this class. BlobStorageFacade encapsulates the blob container and blob properties objects used to access a specific named blob storage from the cloud. This class provides an agile way to perform insert and delete actions to blob storage (update can be done by changing the overwrite flag to false). To reach this goal, the constructor of this class accepts three parameters of blob storage: BlobContents, BlobProperties, and a boolean flag of overwrite. • BlobStorageActionStatus is an abstract base class. This class uses a combination of the bridge design pattern and the command design pattern (without supporting the memento pattern, because there is actually no transaction supported from the client side in the cloud platform. The constructor of this class has exactly the same structure as that of BlobStorageFacade. The responsibility of this class is to spawn a worker thread to handle the long-running blob storage access tasks and to provide the progress status of the data access. BlobStorageActionStatus has two derived classes, CreateBlobStatus and DeleteBlobStatus, which are responsible for blob storage creation and deletion respectively. All derived classes implement the ICommand interface, which provides an Excuse() function to update the progress status. . application may potentially be used as a utility tool for anyone who needs to transmit a large amount of data to a cloud blob. In this exercise we will walk you through creation of a Windows- based

Ngày đăng: 05/07/2014, 01:20

Xem thêm: Introducing Windows Azure- P25 pot