Connecting to the storage emulator
The Windows Azure SDK provides a compute emulator and a storage emulator that work in a development environment to provide a local emulation of Windows Azure hosted services and storage services. There are some differences in functionality between storage services and the storage emulator. Prior to Windows Azure SDK v1.3, the storage emulator was named development storage.
Note
By default, the storage emulator uses SQL Server Express, but it can be configured to use SQL Server.
An immediate difference is that the storage emulator supports only one account name and access key. The account name is hard-coded to be devstoreaccount1
. The access key is hard-coded to be:
Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
Another difference is that the storage endpoints are constructed differently for the storage emulator. The storage service uses URL subdomains to distinguish the endpoints for the various types of storage. For example, the endpoint for the Blob service for a storage account named myaccount is:
myaccount.blob.core.windows.net
The endpoints for the other storage types are constructed similarly by replacing the word blob
with either table
or queue
.
This differentiation by subdomain name is not used in the storage emulator which is hosted on the local host at 127.0.0.1
. Instead, the storage emulator distinguishes the endpoints for various types of storage through use of different ports. Furthermore, the account name, rather than being part of the subdomain, is provided as part of the URL. Consequently, the endpoints used by the storage emulator are as follows:
127.0.0.1:10000/devstoreaccount1 Blob
127.0.0.1:10001/devstoreaccount1 Queue
127.0.0.1:10002/devstoreaccount1 Table
The Windows Azure Storage Client library hides much of this complexity but an understanding of it remains important in case something goes wrong. The account name and access key are hard-coded into the Storage Client library, which also provides simple access to an appropriately constructed CloudStorageAccount
object.
The Storage Client library also supports a special value for the DataConnectionString
in the service configuration file. Instead of specifying the account name and access key, it is sufficient to specify the following:
UseDevelopmentStorage=true
For example, this is specified as follows in the service configuration file:
<Setting
name="DataConnectionString"
value="UseDevelopmentStorage=true"
/>
This value can also be used for the Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
data connection string required for Windows Azure Diagnostics.
The CloudStorageAccount.Parse()
and CloudStorageAccount.FromConnectionString()
methods handle this value in a special way to create a CloudStorageAccount
object that can be used to authenticate against the storage emulator.
In this recipe, we will learn how to connect to the storage emulator.
Getting ready
This recipe assumes the following is in the application configuration file:
<appSettings> <add key="DataConnectionString"value="UseDevelopmentStorage=true"/> </appSettings>
How to do it...
We are going to connect to the storage emulator in various ways and perform some operations on blobs. We do this as follows:
Add a class named
StorageEmulatorExample
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 private members to the class:
private String containerName; private String blobName;
Add the following constructor to the class:
StorageEmulatorExample(String containerName, String blobName) { this.containerName = containerName; this.blobName = blobName; }
Add the following method, using the configuration file, to the class:
private void UseConfigurationFile() { CloudStorageAccount cloudStorageAccount =CloudStorageAccount.Parse( ConfigurationManager.AppSettings["DataConnectionString"]); CloudBlobClient cloudBlobClient =cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer =cloudBlobClient.GetContainerReference(containerName); cloudBlobContainer.Create(); }
Add the following method, using an explicit storage account, to the class:
private void CreateStorageCredential() { String baseAddress ="http://127.0.0.1:10000/devstoreaccount1"; String accountName = "devstoreaccount1"; String accountKey ="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="; StorageCredentialsAccountAndKey storageCredentials = newStorageCredentialsAccountAndKey(accountName, accountKey); CloudBlobClient cloudBlobClient =new CloudBlobClient(baseAddress, storageCredentials); CloudBlobContainer cloudBlobContainer =cloudBlobClient.GetContainerReference(containerName); CloudBlockBlob cloudBlockBlob =cloudBlobContainer.GetBlockBlobReference(blobName); cloudBlockBlob.UploadText("If we shadows have offended."); cloudBlockBlob.Metadata["{METADATA_KEY}"] ="{METADATA_VALUE}"; cloudBlockBlob.SetMetadata(); }
Add the following method, using the
CloudStorageAccount.DevelopmentStorageAccount
property, to the class:private void UseDevelopmentStorageAccount() { CloudStorageAccount cloudStorageAccount =CloudStorageAccount.DevelopmentStorageAccount; CloudBlobClient cloudBlobClient =cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer =cloudBlobClient.GetContainerReference(containerName); CloudBlockBlob cloudBlockBlob =cloudBlobContainer.GetBlockBlobReference(blobName); cloudBlockBlob.FetchAttributes(); BlobAttributes blobAttributes = cloudBlockBlob.Attributes; String metadata =blobAttributes.Metadata["{METADATA_KEY}"]; }
Add the following method, using the methods added earlier, to the class:
public static void UseStorageEmulatorExample() { String containerName = "{CONTAINER_NAME}"; String blobName = "{BLOB_NAME}"; StorageEmulatorExample example =new StorageEmulatorExample(containerName, blobName); example.UseConfigurationFile(); example.CreateStorageCredential(); example.UseDevelopmentStorageAccount(); }
How it works...
In steps 1 and 2, we set up the class. In step 3, we add some private members for the container name and blob name, which we initialize in the constructor we add in step 4.
In step 5, we retrieve a data connection string from a configuration file and pass it into CloudStorageAccount.Parse()
to create a CloudStorageAccount
instance. We use this to get references to a CloudBlobContainer
instance for the specified container. We use this to create the container.
In step 6, we create a StorageCredentialsAccountAndKey
instance from the explicitly provided storage emulator values for account name and access key. We use the resulting StorageCredential
to initialize a CloudStorageClient
object, explicitly providing the storage emulator endpoint for blob storage. We then create a reference to a blob, upload some text to the blob, define some metadata for the blob, and finally update the blob with it. We must replace {METADATA_KEY}
AND {METADATA_VALUE}
with actual values.
In step 7, we initialize a CloudStorageAccount
from the hard-coded CloudStorageAccount
property exposed by the class. We then get a CloudBlockBlob
object, which we use to retrieve the properties stored on the blob and retrieve the metadata we added in step 6. We should replace {METADATA_KEY}
with the same value that we used in step 6.
In step 8, we add a helper method that invokes each of the methods we added earlier. We must replace {CONTAINER_NAME}
and {BLOB_NAME}
with appropriate names for the container and blob.
There's more...
Fiddler is a program that captures HTTP traffic, which makes it very useful for diagnosing problems when using the Windows Azure Storage Service. Its use is completely transparent when cloud storage is being used. However, the data connection string must be modified if you want Fiddler to be able to monitor the traffic. The data connection string must be changed to the following:
UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler
Fiddler can be downloaded from the following URL: