Connecting to the Windows Azure Storage Service
In a Windows Azure hosted service, the storage account name and access key are stored in the service configuration file. By convention, the account name and access key for data access are provided in a setting named DataConnectionString
. The account name and access key needed for Windows Azure diagnostics must be provided in a setting named Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
.
Note
The DataConnectionString
setting must be declared in the ConfigurationSettings
section of the service definition file. However, unlike other settings, the connection string setting for Windows Azure diagnostics is implicitly defined when the diagnostics module is specified in the Imports
section of the service definition file. Consequently, it must not be specified in the ConfigurationSettings
section.
A best practice is to use different storage accounts for application data and diagnostic data. This reduces the possibility of application data access being throttled by competition for concurrent writes from the diagnostics monitor. It also provides a security boundary between application data and diagnostics data, as diagnostics data may be accessed by individuals who should have no access to application data.
In the Windows Azure Storage Client library, access to the storage service is through one of the client classes. There is one client class for each of Blob service, Queue service, and Table service—CloudBlobClient
, CloudQueueClient
, and CloudTableClient
respectively. Instances of these classes store the pertinent endpoint, as well as the account name and access key.
The CloudBlobClient
class provides methods to access containers list their contents and get references to containers and blobs. The CloudQueueClient
class provides methods to list queues and to get a reference to the CloudQueue
instance used as an entry point to the Queue service functionality. The CloudTableClient
class provides methods to manage tables and to get the TableServiceContext
instance used to access the WCF Data Services functionality used in accessing the Table service. Note that CloudBlobClient
, CloudQueueClient
, and CloudTableClient
instances are not thread safe so distinct instances should be used when accessing these services concurrently.
The client classes must be initialized with the account name and access key, as well as the appropriate storage service endpoint. The Microsoft.WindowsAzure
namespace has several helper classes. The StorageCredentialsAccountAndKey
class initializes a StorageCredential
instance from an account name and access key while the StorageCredentialsSharedAccessSignature
class initializes a StorageCredential
instance from a shared access signature. The CloudStorageAccount
class provides methods to initialize an encapsulated StorageCredential
instance directly from the service configuration file.
In this recipe, we will learn how to use CloudBlobClient
, CloudQueueClient
, and CloudTableClient
instances to connect to the storage service.
Getting ready
This recipe assumes the application configuration file contains the following:
<appSettings> <add key="DataConnectionString"value="DefaultEndpointsProtocol=https;AccountName={ACCOUNT_NAME};AccountKey={ACCOUNT_KEY}"/> <add key="AccountName" value="{ACCOUNT_NAME}"/> <add key="AccountKey" value="{ACCOUNT_KEY}"/> </appSettings>
Note
Downloading the example code for this book
You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.
We must replace {ACCOUNT_NAME}
and {ACCOUNT_KEY}
with appropriate values for the storage account name and access key.
How to do it...
We are going to connect to the Table service, the Blob service, and the Queue service to perform a simple operation on each. We do this as follows:
Add a new class named
ConnectingToStorageExample
to the project.Add the following
using
statements to the top of the class file:using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient; using System.Configuration;
Add the following method, connecting to the blob service, to the class:
private static void UseCloudStorageAccountExtensions() { CloudStorageAccount cloudStorageAccount =CloudStorageAccount.Parse(ConfigurationManager.AppSettings["DataConnectionString"]); CloudBlobClient cloudBlobClient =cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer =cloudBlobClient.GetContainerReference("{CONTAINER_NAME}"); cloudBlobContainer.Create(); }
Add the following method, connecting to the Table service, to the class:
private static void UseCredentials() { String accountName = ConfigurationManager.AppSettings["AccountName"]; String accountKey = ConfigurationManager.AppSettings["AccountKey"]; StorageCredentialsAccountAndKey storageCredentials =new StorageCredentialsAccountAndKey(accountName, accountKey); CloudStorageAccount cloudStorageAccount =new CloudStorageAccount(storageCredentials, true); CloudTableClient tableClient =new CloudTableClient(cloudStorageAccount.TableEndpoint.AbsoluteUri,storageCredentials); Boolean tableExists =tableClient.DoesTableExist("{TABLE_NAME}"); }
Add the following method, connecting to the Queue service, to the class:
private static void UseCredentialsWithUri() { String accountName = ConfigurationManager.AppSettings["AccountName"]; String accountKey = ConfigurationManager.AppSettings["AccountKey"]; StorageCredentialsAccountAndKey storageCredentials =new StorageCredentialsAccountAndKey(accountName, accountKey); String baseUri =String.Format("https://{0}.queue.core.windows.net/",accountName); CloudQueueClient cloudQueueClient =new CloudQueueClient(baseUri, storageCredentials); CloudQueue cloudQueue =cloudQueueClient.GetQueueReference("{QUEUE_NAME}"); Boolean queueExists = cloudQueue.Exists(); }
Add the following method, using the other methods, to the class:
public static void UseConnectionToStorageExample() { UseCloudStorageAccountExtensions(); UseCredentials(); UseCredentialsWithUri(); }
How it works...
In steps 1 and 2, we set up the class.
In step 3, we implement the standard way to access the storage service using the Storage Client library. We use the static CloudStorageAccount.Parse()
method to create a CloudStorageAccount
instance from the value of the connection string stored in the configuration file. We then use this instance with the CreateCloudBlobClient()
extension method to the CloudStorageAccount
class to get the CloudBlobClient
instance we use to connect to the Blob service. We can also use this technique with the Table service and the Queue service using the relevant extension methods for them: CreateCloudTableClient()
and CreateCloudQueueClient()
respectively. We complete this example by using the CloudBlobClient
instance to get a CloudBlobContainer
reference to a container and then fetch its attributes. We need to replace {CONTAINER_NAME}
with the name for a container.
In step 4, we create a StorageCredentialsAccountAndKey
instance directly from the account name and access key. We then use this to construct a CloudStorageAccount
instance, specifying that any connection should use HTTPS. Using this technique, we need to provide the Table service endpoint explicitly when creating the CloudTableClient
instance. We then use this to verify the existence of a table. We need to replace {TABLE_NAME}
with the name for a table. We can use the same technique with the Blob service and Queue service by using the relevant CloudBlobClient
or CloudQueueClient
constructor.
In step 5, we use a similar technique except that we avoid the intermediate step of using a CloudStorageAccount
instance and explicitly provide the endpoint for the Queue service. We use the CloudQueueClient
instance created in this step to verify the existence of a queue. We need to replace {QUEUE_NAME}
with the name of a queue. Note that we have hard-coded the endpoint for the Queue service.
In step 6, we add a method that invokes the methods added in the earlier steps.