Quantcast
Channel: Microsoft Azure Storage Team Blog
Viewing all 167 articles
Browse latest View live

Windows Azure Storage Client Library for Java v. 0.5.0

$
0
0

We are pleased to announce an updated release of the Windows Azure Storage Client for Java. This release includes several notable features such as logging support, new API overloads, and full support for the 2013-08-15 REST storage server version. (See here for details). As usual all of the source code is available via github (note the updated location). You can download the latest binaries via maven:

<dependency>
<groupId>com.microsoft.windowsazure.storage</groupId>
<artifactId>microsoft-windowsazure-storage-sdk</artifactId>
<version>0.5.0</version>
</dependency>

Emulator Guidance

Please note, that the 2013-08-15 REST is currently unsupported by the storage emulator. An updated Windows Azure Storage Emulator is expected to ship with full support of these new features in the next couple of months. Users attempting to develop against the current version of the Storage emulator will receive Bad Request errors in the interim.  Until then, users wanting to use the new features would need to develop and test against a Windows Azure Storage Account to leverage the 2013-08-15 REST version.

Samples

We have provided a series of samples on github to help clients get up and running with each storage abstraction and to illustrate some additional key scenarios. To run a given sample using Eclipse, simply load the samples project and update the following line in Utility.java to provide your storage credentials.

publicstaticfinal String storageConnectionString = "DefaultEndpointsProtocol=http;AccountName=[ACCOUNT_NAME];AccountKey=[ACCOUNT_KEY]";

If you wish to use fiddler to inspect traffic while running the samples, please uncomment the following 2 lines in Utility.java.
// System.setProperty("http.proxyHost", "localhost");
// System.setProperty("http.proxyPort", "8888");

After updating Utiltity.java, right-click on the specific project you want to run and click on Run As Java Application.

A Note about Packaging and Versioning

We have migrated the Storage package out of the larger Windows Azure SDK for Java for this release. Developers who are currently leveraging the existing SDK will need to update their dependencies accordingly. Furthermore, the package names have been changed to reflect this new structure:

  • com.microsoft.windowsazure.storage– RetryPolicies, LocationMode, StorageException, Storage Credentials etc. All public classes that are common across services
  • com.microsoft.windowsazure.storage.blob - Blob convenience implementation, applications utilizing Windows Azure Blobs should include this namespace in their import statements
  • com.microsoft.windowsazure.storage.queue - Queue convenience implementation, applications utilizing Windows Azure Queues should include this namespace in their import statements
  • com.microsoft.windowsazure.storage.table - Table convenience implementation, applications utilizing Windows Azure Tables should include this namespace in their import statements

For a more detailed list of changes in this release, please see the Change Log & Breaking Changes section below.

We are also adopting the SemVer specification regarding all of the storage client sdk components we provide. This will help provide consistent and predictable versioning guidance to developers who leverage the sdk.

Whats New

The 0.5.0 version of the Java client library provides full support for the 2013-08-15 REST service version (you can read more about the supported features here), as well as key client improvements listed below.

Support for Read Access Geo Redundant Storage

This release has full support for Read Access to the storage account data in the secondary region. This functionality needs to be enabled via the portal for a given storage account. You can read more about RA-GRS here. As mentioned in the blog, there is a getServiceStats API for Cloud[Blob|Table|Queue]Client that allows applications to easily retrieve the replication status and LastSyncTime for each service. Setting the location mode on the client object and invoking getServiceStats is shown in the example below. The LocationMode can also be configured on a per request basis by setting it on the RequestOptions object.

CloudStorageAccount httpAcc = CloudStorageAccount.parse(connectionString);
CloudTableClient tClient = httpAcc.createCloudTableClient();

// Set the LocationMode to SECONDARY_ONLY since getServiceStats is supported only on the secondary endpoints.
tClient.setLocationMode(LocationMode.SECONDARY_ONLY);
ServiceStats stats = tClient.getServiceStats();
Date lastSyncTime = stats.getGeoReplication().getLastSyncTime();

System.out.println(String.format("Replication status = %s and LastSyncTime = %s",stats.getGeoReplication().getStatus().toString(), lastSyncTime != null ? lastSyncTime.toString(): "empty"));
Expanded Table Protocol Support (JSON)

In the previous release all table traffic was sent using the AtomPub protocol. With the current release the default protocol is now JSON minimal metadata. (You can read more details regarding these protocols as well as view sample payloads here) This improvement allows the client to dramatically reduce the payload size of the request as well as reduce the CPU required to process the request. These improvements allow client applications to scale higher and realize lower overall latencies for table operations. An example of setting the tablePayloadFormat on the client object is shown in the example below. The tablePayloadFormat can also be configured on a per request basis by setting it on the TableRequestOptions object.

CloudStorageAccount httpAcc = CloudStorageAccount.parse(connectionString);
CloudTableClient tClient = httpAcc.createCloudTableClient();

// Set the payload format to JsonNoMetadata.
tableClient.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);

When using JsonNoMetadata the client library will “infer” the property types by inspecting the type information on the POJO entity type provided by the client. Additionally, in some scenarios clients may wish to provide the property type information at runtime such as when querying with the DynamicTableEntity or doing complex queries that may return heterogeneous entities. To support this scenario the user should implement PropertyResolver which allows users to return an EdmType for each property based on the data received from the service. The sample below illustrates a propertyResolver implementation.

publicstaticclass Class1 extends TableServiceEntity implements PropertyResolver {
private String A;
privatebyte[] B;

public String getA() {
returnthis.A;
}

publicbyte[] getB() {
returnthis.B;
}

publicvoid setA(final String a) {
this.A = a;
}

publicvoid setB(finalbyte[] b) {
this.B = b;
}

@Override
public EdmType propertyResolver(String pk, String rk, String key, String value) {
if (key.equals("A")) {
return EdmType.STRING;
}
elseif (key.equals("B")) {
return EdmType.BINARY;
}
return null;
}

}

This propertyResolver is set on the TableRequestOptions as shown below.

Class1 ref = new Class1();
ref.setA("myPropVal");
ref.setB(newbyte[] { 0, 1, 2 });
ref.setPartitionKey("testKey");
ref.setRowKey(UUID.randomUUID().toString());

options.setPropertyResolver(ref);

Table Insert Optimizations

In previous versions of the REST api the Prefer header was not supported for Insert operations. As a result, the service would “echo” back the entity content in the response body. With this release all Table Insert operations, including those executed as part of a batch operation, will send the Prefer: return-no-content header to avoid this behavior. This optimization can dramatically reduce latencies for insert operations. Please note that this will cause the resulting HTTP status code on the TableResult for successful inserts to be 204 (no-content) rather than 201 (Created). The echo content behavior can be re-enabled by using the insert(TableEntity, boolean) method and specifying true.

Table Reflection Optimizations

When clients are persisting POJO objects to the Table Service the client can now cache the type and property information to avoid repeated reflection calls. This optimization can dramatically reduce CPU during queries and other table operations. Note, clients can disable this cache by setting TableServiceEntity.setReflectedEntityCacheDisabled(true).

New APIs and overloads

In response to customer feedback we have expanded the api surface to add additional conveniences, including:

  • CloudBlob.downloadRange
  • CloudBlob.downloadToByteArray
  • CloudBlob.downloadRangeToByteArray
  • CloudBlob.uploadFromByteArray
  • CloudBlob.uploadFromByteArray
  • CloudBlob.downloadToFile
  • CloudBlob.uploadFromFile
  • CloudBlockBlob.uploadText
  • CloudBlockBlob.downloadText
Logging

The 0.5.0 release supports logging via the SLF4J logging facade. This allows users to utilize various logging frameworks in conjunction with the storage api in order to log information regarding request execution (See below for a table of what information is logged). We plan on providing additional rich logging information in subsequent releases to further assist clients in debugging their applications.

Logged Data

Each log line will include the following data:

  • Client Request ID: Per request ID that is specified by the user in OperationContext
  • Event: Free-form text
  • Any other information, as determined by the user-chosen underlying logging framework

For example, if the underlying logging framework chosen is Simple, the log line might look something like the following:

[main] INFO ROOT - {c88f2fe5-7150-467b-8571-7aa40a9a3e27}: {Starting operation.}

Trace Levels

Level

Events

ERROR

If an exception cannot or will not be handled internally and will be thrown to the user; it will be logged as an error.

WARN

If an exception is caught and might be handled internally, it will be logged as a warning. Primary use case for this is the retry scenario, where an exception is not thrown back to the user to be able to retry. It can also happen in operations such as CreateIfNotExists, where we handle the 404 error silently.

INFO

The following info will be logged:

  • Right after the user calls a method to start an operation, request details such as URI* and client request ID will be logged.
  • Important milestones such as Sending Request Start/End, Upload Data Start/End, Receive Response Start/End, Download Data Start/End will be logged to mark the timestamps.
  • Right after the headers are received, response details such as request ID and HTTP status code will be logged.
  • If an operation fails and the storage client decides to retry, the reason for that decision will be logged along with when the next retry is going to happen.
  • All client-side timeouts will be logged when storage client decides to abort a pending request.

DEBUG

Nothing logged at this level currently.

TRACE

Nothing logged at this level currently.

*Please take care when enabling logging while using SAS as the SAS tokens themselves will be logged. As such, clients using SAS with logging enabled should take care to protect the logging output of their application.

Enabling Logging

A key concept is the opt-in / opt-out model that the client provides to tracing. In typical applications it is customary to enable tracing at a given verbosity for a specific class. This works fine for many client applications, however for cloud applications that are executing at scale, this approach may generate much more data than what is required by the user. As such we have provided an opt-in model for logging which allows clients to configure listeners at a given verbosity, but only log specific requests if and when they choose. Essentially this design provides the ability for users to perform “vertical” logging across layers of the stack targeted at specific requests rather than “horizontal” logging which would record all traffic seen by a specific class or layer.

Another key concept is the facade logging model. SLF4J is a facade and does not provide a logging framework. Instead, the user may choose the underlying logging system, whether it be the built in jdk logger or one of the many open-source alternatives (see the SLF4J site for a list of compatible loggers). Once a logger is selected clients can add the corresponding jar which binds the facade to the chosen framework and the application will log using the settings specific to that framework. As a result, if the user has already chosen a logging framework for their application the storage sdk will work with that framework rather than requiring a separate one. The façade model allows users to change the logging framework easily throughout the development process and avoid any framework lock in.

Choose a Logging Framework

To enable logging, first choose a logging framework. If you already have one, simply add the corresponding SLF4J binding jar to your classpath or add a dependency to it in Maven. If you do not already have a logging framework, you will need to choose one and add it to your classpath or add a dependency to it in Maven. If it does not natively implement SLF4J you will also need to add the corresponding SLF4J binding jar. SLF4J comes with its own logger implementation called Simple, so we will use that in our example below. Either download the slf4j-simple-1.7.5.jar from SLF4J and add it to your classpath or include the following Maven dependency:

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>


This will enable logging to the console with a default log level of info. To change the logging settings, follow the directions for Simple.

1. Turn Logging on in the SDK

By default, the Azure Storage Java SDK will not produce any logs, even if it finds a logging framework and corresponding SLF4J binding. This way, the user is not forced to edit any log framework settings if they do not want Azure Storage logs. If logging is turned on, the root logger settings will be used by default. A different logger may be specified on a per request basis.

Example 1: Enable logging on for every request:

OperationContext.setLoggingEnabledByDefault(true);

Example 2: Enable logging for a single request:
OperationContext ctx = new OperationContext();
ctx.setLoggingEnabled(true);
blockBlobRef.upload(srcStream, -1, null /* accessCondition */, null /* requestOptions */, ctx);

Example 3: To use a specific logger for a request:
OperationContext ctx = new OperationContext();

// turn logging on for that operation context
ctx.setLoggingEnabled(true);

// the slf4j logger factory will get the logger with this name and use
// this logger’s settings include location to log and log level
ctx.setLogger(LoggerFactory.getLogger(“MyLogger”));
blockBlobRef.upload(srcStream, -1, null /* accessCondition */, null /* requestOptions */, ctx);

With client side logging used in conjunction with storage service logging clients can now get a complete view of their application from both the client and server perspectives.

Change Log & Breaking Changes

As mentioned above, this release supports the 2013-08-15 REST service version and details of features and changes in the version can be found in MSDN and also blogged here. In addition to the REST changes, this release includes several client side changes and features. Key changes to note for this release are highlighted below. You can view the complete ChangeLog and BreakingChanges log on github.

Common

  • Package Restructure
  • RetryResult has been replaced by RetryInfo which provides additional functionality
  • Event operations (including event firing) that occur during a request are no longer synchronized, (thread safety is now guaranteed by a CopyOnWriteArrayList of the event listeners)
  • OperationContext.sendingRequest event is now fired prior to the connection being established, allowing users to alter headers

Blob

  • Blob downloadRange now downloads to a Stream. The previous downloadRange has been renamed to downloadRangeToByteArray.
  • Removed sparse page blob feature
  • CloudBlobContainer.createIfNotExist was renamed to CloudBlobContainer.createIfNotExists
  • CloudBlobClient.streamMinimumReadSizeInBytes has been removed. This functionality is now provided by CloudBlob.streamMinimumReadSizeInBytes (settable per-blob, not per-client.)
  • CloudBlobClient.pageBlobStreamWriteSizeInBytes and CloudBlobClient.writeBlockSizeInBytes have been removed. This functionality is now provided by CloudBlob.streamWriteSizeInBytes.

Table

  • Removed id field (along with getId, setId) from TableResult
  • CloudTable.createIfNotExist was renamed to CloudTable.createIfNotExists
  • Inserts in operations no longer echo content. Echo content can be re-enabled by using the insert(TableEntity, boolean) method and specifying true. This will cause the resulting HTTP status code on the TableResult for successful inserts to be 204 (no-content) rather than 201 (Created).
  • JsonMinimalMetadata is now the default payload format (rather than AtomPub). Payload format can be specified for all table requests by using CloudTableClient.setTablePayloadFormat or for an individual table request by using TableRequestOptions.setTablePayloadFormat.

Queue

  • CloudQueue.createIfNotExist was renamed to CloudQueue.createIfNotExists

Summary

We are continuously making improvements to the developer experience for Windows Azure Storage and very much value your feedback in the comments section below, the forums, or GitHub. If you hit any issues, filing them on GitHub will also allow you to track the resolution.

Joe Giardino, Veena Udayabhanu, Emily Gerner, and Adam Sorrin

Resources

Source (github)

Maven

BreakingChanges

ChangeLog

Windows Azure Storage Release - Introducing CORS, JSON, Minute Metrics, and More

Windows Azure Tables: Introducing JSON

Windows Azure Storage Redundancy Options and Read Access Geo Redundant Storage

SemVer Specification


Windows Azure Storage Client Library for C++ Preview

$
0
0

We are excited to announce the availability of our new Windows Azure Storage Client Library for C++. This is currently a Preview release, which means the library should not be used in your production code just yet. Instead, please kick the tires and give us any feedback you might have for us to improve/change the interface based on feedback for the GA release. This blog post serves as an overview of the library.

Please refer to SOSP Paper - Windows Azure Storage: A Highly Available Cloud Storage Service with Strong Consistency for more information on Windows Azure Storage.

Emulator Guidance

Please note, that the 2013-08-15 REST version, which this library utilizes, is currently unsupported by the storage emulator. An updated Windows Azure Storage Emulator is expected to ship with full support of these new features in the next month. Users attempting to develop against the current version of the Storage emulator will receive Bad Request errors in the interim.  Until then, users wanting to use the new features would need to develop and test against a Windows Azure Storage Account to leverage the 2013-08-15 REST version.

Supported Platforms

In this release, we provide x64 and x86 versions of the library for both Visual Studio 2012 (v110) and Visual Studio 2013 (v120) platform toolsets. Therefore you will find 8 build flavors in the package:

  1. Release, x64, v120
  2. Debug, x64, v120
  3. Release, Win32, v120
  4. Debug, Win32, v120
  5. Release, x64, v110
  6. Debug, x64, v110
  7. Release, Win32, v110
  8. Debug, Win32, v110

Where is it?

The library can be downloaded from NuGet and full source code is available on GitHub. NuGet packages are created using the CoApp tools and therefore consist of 3 separate packages:

  • wastorage.0.2.0-preview.nupkg: This package contains header and LIB files required to develop your application. This is the package you need to install, which has a dependency on the redist package and thus will force NuGet to install that one automatically.
  • wastorage.redist.0.2.0-preview.nupkg: This package contains DLL files required to run and redistribute your application.
  • wastorage.symbols.0.2.0-preview.nupkg: This package contains symbols for the respective DLL files and therefore is an optional package.

The package also contains a dependency on C++ REST SDK, which will also be automatically installed by NuGet. The C++ REST SDK (codename "Casablanca") is a Microsoft project for cloud-based client-server communication in native code and provides support for accessing REST services from native code on multiple platforms by providing asynchronous C++ bindings to HTTP, JSON, and URIs. Windows Azure Storage Client Library uses it to communicate with the Windows Azure Storage Blob, Queue, and Table services.

What do you get?

Here is a summary of the functionality you will get by using Windows Azure Storage Client Library instead of directly talking to the REST API:

  • Easy-to-use implementations of the entire Windows Azure Storage REST API version 2013-08-15
  • Retry policies that retry certain failed requests using an exponential or linear back off algorithm
  • Streamlined authentication model that supports both Shared Keys and Shared Authentication Signatures
  • Ability to dive into the request details and results using an operation context and ETW logging
  • Blob uploads regardless of size and blob type, and parallel block/page uploads configurable by the user
  • Blob streams that allow reading from or writing to a blob without having to deal with specific upload/download APIs
  • Full MD5 support across all blob upload and download APIs
  • Table layer that uses the new JSON support on Windows Azure Storage announced in November 2013
  • Entity Group Transaction support for Table service that enables multiple operations within a single transaction

Support for Read Access Geo Redundant Storage

This release has full support for Read Access to the storage account data in the secondary region. This functionality needs to be enabled via the portal for a given storage account, you can read more about RA-GRS here.

How to use it?

After installing the NuGet package, all header files you need to use will be located in a folder named “was” (stands for Windows Azure Storage). Under this directory, the following header files are critical:

  • blob.h: Declares all types related to Blob service
  • queue.h: Declares all types related to Queue service
  • table.h: Declares all types related to Table service
  • storage_account.h: Declares the cloud_storage_account type that can be used to easily create service client objects using an account name/key or a connection string
  • retry_policies.h: Declares different retry policies available to use with all operations

So, you can start with including the headers you are going to use:

#include"was/storage_account.h"
#include"was/queue.h"
#include"was/table.h"
#include"was/blob.h"

Then we will create a cloud_storage_account object, which enables us to create service client objects later in the code. Please note that we are using https below for a secure connection, but http is very useful when you are debugging your application.

wa::storage::cloud_storage_account storage_account = wa::storage::cloud_storage_account::parse(U("AccountName=<account_name>;AccountKey=<account_key>;DefaultEndpointsProtocol=https"));

Blobs

Here we create a blob container, a blob with “some text” in it, download it, and then list all the blobs in our container:

// Create a blob container
wa::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();
wa::storage::cloud_blob_container container = blob_client.get_container_reference(U("mycontainer"));
container.create_if_not_exists();

// Upload a blob
wa::storage::cloud_block_blob blob1 = container.get_block_blob_reference(U("myblob"));
blob1.upload_text(U("some text"));

// Download a blob
wa::storage::cloud_block_blob blob2 = container.get_block_blob_reference(U("myblob"));
utility::string_t text = blob2.download_text();

// List blobs
wa::storage::blob_result_segment blobs = container.list_blobs_segmented(wa::storage::blob_continuation_token());

Tables

The sample below creates a table, inserts an entity with couple properties of different types, and finally retrieves that specific entity. In the first retrieve operation, we do a point query and retrieve the specific entity. In the query operation, on the other hand, we query all entities with PartitionKey is equal to “partition” and RowKey is greater than or equal to “m”, which will eventually get us the original entity we inserted.

For more information on Windows Azure Tables, please refer to the Understanding the Table Service Data Model article and the How to get most out of Windows Azure Tables blog post.

// Create a table
wa::storage::cloud_table_client table_client = storage_account.create_cloud_table_client();
wa::storage::cloud_table table = table_client.get_table_reference(U("mytable"));
table.create_if_not_exists();

// Insert a table entity
wa::storage::table_entity entity(U("partition"), U("row"));
entity.properties().insert(wa::storage::table_entity::property_type(U("PropertyA"), wa::storage::table_entity_property(U("some string"))));
entity.properties().insert(wa::storage::table_entity::property_type(U("PropertyB"), wa::storage::table_entity_property(utility::datetime::utc_now())));
entity.properties().insert(wa::storage::table_entity::property_type(U("PropertyC"), wa::storage::table_entity_property(utility::new_uuid())));
wa::storage::table_operation operation1 = wa::storage::table_operation::insert_or_replace_entity(entity);
wa::storage::table_result table_result = table.execute(operation1);

// Retrieve a table entity
wa::storage::table_operation operation2 = wa::storage::table_operation::retrieve_entity(U("partition"), U("row"));
wa::storage::table_result result = table.execute(operation2);

// Query table entities
wa::storage::table_query query;
query.set_filter_string(wa::storage::table_query::combine_filter_conditions(
wa::storage::table_query::generate_filter_condition(U("PartitionKey"), wa::storage::query_comparison_operator::equal, U("partition")),
wa::storage::query_logical_operator::and,
wa::storage::table_query::generate_filter_condition(U("RowKey"), wa::storage::query_comparison_operator::greater_than_or_equal, U("m"))));
std::vector<wa::storage::table_entity> results = table.execute_query(query);

Queues

In our final example, we will create a queue, add a message to it, retrieve the same message, and finally update it:

// Create a queue
wa::storage::cloud_queue_client queue_client = storage_account.create_cloud_queue_client();
wa::storage::cloud_queue queue = queue_client.get_queue_reference(U("myqueue"));
queue.create_if_not_exists();

// Add a queue message
wa::storage::cloud_queue_message message1(U("mymessage"));
queue.add_message(message1);

// Get a queue message
wa::storage::cloud_queue_message message2 = queue.get_message();

// Update a queue message
message2.set_content(U("changedmessage"));
queue.update_message(message2, std::chrono::seconds(30), true);

How to debug it?

When things go wrong, you might get an exception from one of your calls. This exception will be of type wa::storage::storage_exception and contain detailed information about what went wrong. Consider the following code:

try
{
blob1.download_attributes();
}
catch (const wa::storage::storage_exception& e)
{
std::cout << "Exception: "<< e.what() << std::endl;
ucout << U("The request that started at ") << e.result().start_time().to_string() << U(" and ended at ") << e.result().end_time().to_string() << U(" resulted in HTTP status code ") << e.result().http_status_code() << U(" and the request ID reported by the server was ") << e.result().service_request_id() << std::endl;
}

When run on a non-existing blob, this code will print out:

Exception: The specified blob does not exist.

The request that started at Fri, 13 Dec 2013 18:31:11 GMT and ended at Fri, 13 Dec 2013 18:31:11 GMT resulted in HTTP status code 404 and the request ID reported by the server was 5de65ae4-9a71-4b1d-9c99-cc4225e714c6

The library also provides the type wa::storage::operation_context, which is supported by all APIs, to obtain more information about what is being done during an operation. Now consider the following code:

wa::storage::operation_context context;

context.set_sending_request([] (web::http::http_request& request, wa::storage::operation_context)
{
ucout << U("The request is being sent to ") << request.request_uri().to_string() << std::endl;
});

context.set_response_received([] (web::http::http_request&, const web::http::http_response& response, wa::storage::operation_context)
{
ucout << U("The reason phrase is ") << response.reason_phrase() << std::endl;
});

try
{
blob1.download_attributes(wa::storage::access_condition(), wa::storage::blob_request_options(), context);
}
catch (const wa::storage::storage_exception& e)
{
std::cout << "Exception: "<< e.what() << std::endl;
}

ucout << U("Executed ") << context.request_results().size() << U(" request(s) to perform this operation and the last request's status code was ") << context.request_results().back().http_status_code() << std::endl;

Again, when run on a non-existing blob, this code will print out:

The request is being sent to http://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=90

The reason phrase is The specified blob does not exist.

Exception: The specified blob does not exist.

Executed 1 request(s) to perform this operation and the last request's status code was 404

Samples

We have provided sample projects on GitHub to help get you up and running with each storage abstraction and to illustrate some additional key scenarios. All sample projects are found under the folder named “samples”.

Open the samples solution file named “Microsoft.WindowsAzure.Storage.Samples.sln” in Visual Studio. Update your storage credentials in the samples_common.h file under the Microsoft.WindowsAzure.Storage.SamplesCommon project. Go to the Solution Explorer window and select the sample project you want to run (for example, Microsoft.WindowsAzure.Storage.BlobsGettingStarted) and choose “Set as StartUp Project” from the Project menu (or, alternatively, right-click the project, then choose the same option from the context menu).

Summary

We welcome any feedback you may have in the comments section below, the forums, or GitHub. If you hit any bugs, filing them on GitHub will also allow you to track the resolution.

Serdar Ozler, Mike Fisher, and Joe Giardino

Resources

Source (GitHub)

Binaries (NuGet)

Windows Azure Storage Release - Introducing CORS, JSON, Minute Metrics, and More

Windows Azure Tables: Introducing JSON

Windows Azure Storage Emulator 2.2.1 Preview Release with support for “2013-08-15” version

$
0
0

We are excited to announce the release of a preview update to the Windows Azure Storage Emulator that supports the newly announced features for version “2013-08-15” such as CORS, JSON, etc.

The Windows Azure Storage Emulator 2.2.1 Preview Release MSI package can be found here.

Installation steps

This is a preview release and requires that Windows Azure SDK 2.2 be already installed. The installer does not replace the Windows Azure Storage Emulator 2.2 binaries automatically. Instead, it will drop the binaries under a temporary folder "%ProgramFiles%\Windows Azure Storage Emulator 2.2.1\devstore" for 32-bit OS or "%ProgramFiles(x86)%\Windows Azure Storage Emulator 2.2.1\devstore" for 64-bit OS. We took this approach of not overwriting because of the “preview” nature of this emulator and it allows you to easily revert back to previous emulator if required without requiring uninstallation and reinstallation of SDK 2.2. We therefore recommend backing up the Windows Azure Storage Emulator 2.2 binaries and replacing them with the new binaries. A readme.txt file with the detailed manual steps will be open after the MSI installation is complete.

Please note that this is a preview version and any feedback will be greatly appreciated. Please feel free to leave any comments at the end of this post or at the Windows Azure Storage Forum.

Michael Roberson, Jean Ghanem

 

For your convenience, we are providing the post MSI installation instructions that are part of the readme.txt file that is available once you install below:

[README.TXT]

Windows Azure Storage Emulator 2.2.1 Preview

------------------------------------

PREREQUISITES

Windows Azure SDK 2.2 must already be installed from http://www.microsoft.com/en-us/download/details.aspx?id=40893

SETUP

To use version 2.2.1, follow these steps:

  1. Ensure that Windows Azure SDK 2.2 is installed. The Windows Azure Storage Emulator 2.2.1 will not work unless SDK version 2.2 is installed.
  2. Shut down the Windows Azure Storage Emulator if it is currently running.
  3. Copy all files from the following path:
    • For 32-bit OS: "%ProgramFiles%\Windows Azure Storage Emulator 2.2.1\devstore"
    • For 64-bit OS: "%ProgramFiles(x86)%\Windows Azure Storage Emulator 2.2.1\devstore"

to the following path:

"%ProgramFiles%\Microsoft SDKs\Windows Azure\Emulator\devstore"

If prompted, choose to replace the existing files with the new ones.

UNINSTALLATION

Windows Azure Storage Emulator 2.2.1 maintains backward compatibility with version 2.2, so reverting back to version 2.2 is unnecessary in most cases. To revert anyway, reinstall the Windows Azure SDK 2.2 emulator package from the following website:

http://www.windowsazure.com/en-us/downloads/

Windows Azure Storage: Introducing CORS

$
0
0

We recently released CORS(Cross Origin Resource Sharing) for Windows Azure Storage. CORS is supported for Blob, Table and Queue services and can be enabled for each service through the Windows Azure Storage Client Library 3.0. In this blog, we will explain CORS and how Windows Azure Storage supports CORS with an example. The complete sample code can be found in here.

What is CORS

Web Browsers, also referred to as User Agents, commonly apply same origin restriction policy to network requests. These restrictions prevent client-side web applications running from a specific domain to issue requests to another domain for security reasons. As an example, a piece of JavaScript code loaded as part of http://www.contoso.com cannot issue requests at will to any other domain like http://www.northwindtraders.com since the Web Browser will prevent such requests from executing.

CORS is a mechanism that would relax such restriction and allows domains to give each other permissions for accessing each other’s resources. The User Agent in this case would send extra headers in order to ensure that the JavaScript code loaded from a certain domain say www.contoso.com is allowed to access resources located at www.northwindtraders.com. In this case the latter domain could either reply back with extra headers allowing or denying www.contoso.com access to its resources.

CORS extends HTTP specification and more details can be found at http://www.w3.org/TR/cors/.

Why CORS in Windows Azure Storage

In the absence of CORS, websites that use Windows Azure Storage service would need to act as a proxy for storage calls. All requests to storage would need to be proxied via the service and hence the service would have to scale out their servers in case of load increase. As an example, assume that you have a feature as part of your http://www.contoso.com website where users can upload blobs and you want to persist them in your Windows Azure Storage account contoso.blob.core.windows.net. In this case, the upload would have to be done from the browser to your service which in turn would PUT the data in the storage account. This means you would need to scale out your service whenever there is an increase in your website upload traffic.

With CORS, you can eliminate the need to have your service in the upload path. You would in this case enable CORS on your contoso.blob.core.windows.net storage account and allow contoso.com access. Then, your Javascript code can now directly upload blobs using shared access signatures to your storage account without the need of a proxy service. You can therefore benefit from the massive scale of the Windows Azure Storage service without needing to scale out a service in order to deal with any increase in upload traffic to your website.

Please note that CORS is not an authentication mechanism. Any request made against a storage resource when CORS is enabled must either have a proper authentication signature, or must be made against a public resource.

For more details on CORS for Windows Azure Storage, please refer to the following MSDN documentation http://msdn.microsoft.com/en-us/library/windowsazure/dn535601.aspx.

How Does CORS work

Typically, CORS is accomplished in 2 phases. A preflight Request (OPTIONS) request followed by the actual request i.e. GET, PUT, POST, etc.

In some cases, User Agents will not issue a preflight requests in case of simple requests that are issues with simple methods such as GET.

Preflight Request

Preflight request is a mechanism to query the CORS restriction imposed by the service. The User Agent will issue such request whenever some code as part of the Javascript attempts to send a request to another domain. The Preflight requests is an OPTIONS request that carries the actual request headers, the intended HTTP request and the Originating domain. The recipient service would then evaluate the intended operation based on a pre-configured set of rules that imposes restriction on the origin, requested headers, methods, etc. and would either accept or reject the request. In the case of Windows Azure Storage, CORS rules are configured per Service (Blob, Table or Queue) and the preflight requests are evaluated accordingly and not against the individual resource.

Preflight requests are typically cached by the browser and therefore subsequent requests would then skip this step where the actual request will be dispatched in case the cached preflight request had succeeded. The TTL (Time to Live) for cache is configurable.

Actual Request

Actual request refers to the request that the client intended. Such requests also have an additional header “Origin” added by the User Agent.

Successful CORS requests have valid Access-Control response headers. In case no Access-Control headers are returned, the browser would deny the request issuer from seeing the response. Note that the request will still be processed by the service regardless if the Origin header matches a configured rule. The Web Browser decides what part, if any, of the response is exposed to the JavaScript code based on the Access-Control response headers values.

There are some scenarios where the OPTIONS request is not required and therefore is not issued by the Web Browser. Instead Actual requests are directly dispatched and such requests referred to as a simple requests.

CORS Usage scenarios for Windows Azure Storage

As mentioned a typical usage for CORS for Blobs would be to allow direct Web Browser file upload against a Windows Azure Storage account. In this case, a user can use CORS along with SAS (Shared Access Signature) authentication mechanism in order to grant Web Browser write privilege to your storage account. In this case, whenever a user is ready to upload, the JavaScript code would request a blob SAS URL to upload against from your service and then perform a PUT blob request against storage. It is recommended that you limit the access time of the SAS token to the needed duration time in order to limit any security risks and the specific container and or blob to be uploaded. Best practices for SAS usage can be found in here.

Another usage of CORS for Windows Azure Table would be to display table data and possibly manipulate such data from the browser. A typical scenario would be to expose an admin page where a user can change some configuration settings for your website that you persist in a Windows Azure Table. In here, you can use CORS, SAS and JSON to implement such capability as is shown in the code sample. JSON in this case would be a natural fit where you can use JQuery capabilities in JavaScript in order to perform Windows Azure Table request and manipulate the data.

We have provided a sample code where we demo JavaScript code that illustrates Blob upload and listing capabilities as well as Insert and Query Entities capabilities for Windows Azure Table using JQuery.

How to Enable CORS in Windows Azure Storage

To take advantage of CORS, you first need to enable it and configure it on the desired service (Blob, Table, or Queue) separately. You would have to use the latest storage version “2013-08-15” in order to set CORS rules by either using REST APIs or the Windows Azure Storage Client (.Net, Java, C++). Once enabled, you can use any other storage version to interact and issue REST requests against your storage account, such as Put Blob, Query Entity, etc… while staying compliant with CORS.

The MSDN documentation here explains in detail how to configure CORS rules on your account via the REST APIs Set Blob Service Properties (REST API), Set Queue Service Properties (REST API), and Set Table Service Properties (REST API).

In this section, we will briefly explain the different CORS rule configuration and show how to use the Windows Azure Storage Client .NET Library 3.0 in order to enable and configure CORS.

You can configure up to 5 CORS rules for each storage service (i.e. Blob, Table or Queue). An example of a single CORS rule is as such.

<CorsRule>
<AllowedOrigins>http://www.contoso.com, http://www.fabrikam.com</AllowedOrigins>
<AllowedMethods>PUT,GET</AllowedMethods>
<AllowedHeaders>x-ms-meta-data*,x-ms-meta-target,x-ms-meta-source</AllowedHeaders>
<ExposedHeaders>x-ms-meta-*</ExposedHeaders>
<MaxAgeInSeconds>200</MaxAgeInSeconds>
</CorsRule>

For a detailed explanation of each of the xml elements, please refer to this MSDN documentation.

The above rule would permit CORS requests that satisfy the following conditions to be made:

  • Originating from either http://www.contoso.com or http://www.fabrikam.com (AllowedOrigins)
  • And have an HTTP request method of either PUT or GET (AllowedMethods)

Note that you can set both AllowedOrigins and AllowedMethods to *, which means the service would send required CORS headers for all methods (PUT, POST, GET, etc.) when invoked by all origins and is the most typical usage. This does not mean that anyone can access your account. They still need to have proper authentication signature as mentioned before.

The AllowedHeaders would let you configure which request headers the client (JavaScript code) can send against your storage account. This is enforced by the Web Browser who would get to learn about these allowed headers through either the preflight request or the actual request where the Windows Azure Storage service would return such list as part of the Access-Control-Allow-Headers response header. Assume that you don’t want the client to store arbitrary metadata information when calls are issued from the browser and you want to deny storing any info, for instance, in the x-ms-meta-reserved key. In the above example, you would be limiting the metadata to key names either starting with x-ms-meta-data or exactly matching x-ms-meta-target or x-ms-meta-source. Typically you would want to configure this to *, i.e. Allow all request headers.

The ExposedHeaders indicate which response headers can be exposed to the client JavaScript code. This is also enforced by the Web Browser who would learn about these headers through the actual request where Windows Azure Storage Service would return such list of headers as part of the Access-Control-Expose-Headers header response. Typically you would want to configure this to *, i.e. Allow all response headers.

The MaxAgeInSeconds indicates the maximum amount time that a browser can cache the preflight OPTIONS request. In the example above, it is set to 200 seconds. It is recommended to set MaxAgeInSeconds to a relatively large number if the rules do not change frequently since this will increase the responsiveness of your web application by reducing roundtrips and also reduce your storage billing charges as Preflight requests are billed.

Note that CORS rules are evaluated in the order they appear in XML as part of Set Service Properties REST API. This means that you should consider having the more restrictive rules appear first. Any * rule should then appear last. For more details on CORS rule evaluation, please refer to Understanding CORS Rule Evaluation Logic MSDN documentation.

Code Sample for Enabling CORS using Windows Azure Storage Client Library 3.0

Below is a code sample that would enable CORS on a Windows Azure Storage Account for the Blob and Table Service. The code is a snippet from the sample code provided in here.

The code would first GET the current service properties, enable CORS with a single rule of allowing all origins and HTTP methods (PUT, GET, HEAD and POST), and then commits the modified service properties against both the Blob and Table Service.

privatestaticvoid InitializeCors()
{
// CORS should be enabled once at service startup
// Given a BlobClient, download the current Service Properties
ServiceProperties blobServiceProperties = BlobClient.GetServiceProperties();
ServiceProperties tableServiceProperties = TableClient.GetServiceProperties();

// Enable and Configure CORS
ConfigureCors(blobServiceProperties);
ConfigureCors(tableServiceProperties);

// Commit the CORS changes into the Service Properties
BlobClient.SetServiceProperties(blobServiceProperties);
TableClient.SetServiceProperties(tableServiceProperties);
}

privatestaticvoid ConfigureCors(ServiceProperties serviceProperties)
{
serviceProperties.Cors = new CorsProperties();
serviceProperties.Cors.CorsRules.Add(new CorsRule()
{
AllowedHeaders = new List<string>() { "*" },
AllowedMethods = CorsHttpMethods.Put | CorsHttpMethods.Get | CorsHttpMethods.Head | CorsHttpMethods.Post,
AllowedOrigins = new List<string>() { "*" },
ExposedHeaders = new List<string>() { "*" },
MaxAgeInSeconds = 1800 // 30 minutes
});
}

Sample JavaScript Code for uploading a Blob to Windows Azure Storage

This below sample is a code snippet that would allow you to upload a file directly from the Web Browser into Windows Azure Storage using JavaScript. The full code is available in here. The code below is a snippet from the UploadImage.cshtml file.

// Method uploads a blob to Azure Storage by using a Blob SAS URL.
// The Web Browser will add the necessary CORS headers and issue a preflight request if needed.
// blobSasUrl: Blob SAS URL already obtained through an Ajax call to own service
// fileDataAsArrayBuffer: an ArrayBuffer (Byte Array) containing the raw data of the file to be uploaded
function uploadImage(blobSasUrl, fileDataAsArrayBuffer) {
var ajaxRequest = new XMLHttpRequest();

// Once the image is successfully upload, we will call render Image that would show the uploaded image
ajaxRequest.onreadystatechange = function() {return renderImage(ajaxRequest, blobSasUrl)};

try {
// Performing a PutBlob (BlockBlob) against storage
ajaxRequest.open('PUT', blobSasUrl, true);
ajaxRequest.setRequestHeader('Content-Type', 'image/jpeg');
ajaxRequest.setRequestHeader('x-ms-blob-type', 'BlockBlob');
ajaxRequest.send(fileDataAsArrayBuffer);
}
catch (e) {
alert("can't upload the image to server.\n" + e.toString());
}
}

The code first calls into your ASP.NET service in order to retrieve the Blob SAS URL. Here is the code that does that and which eventually calls into the uploadImage method above. It first loads the selected files, then retrieves the Blob SAS URL and finally calls into uploadImage in order to upload the image into Azure Storage.
// This Method is called after the user selects the images to upload.
// It loops over all selected files and uploads them one by one into Azure Storage.
function handleFileSelect(evt) {
var files = evt.target.files; // all selected files (FileList object)

// Loop through the FileList, save them and render image files as thumbnails.
for (var i = 0, file; file = files[i]; i++) {
// Create a reader that would read the entire file data as ArrayBuffer
var reader = new FileReader();

// AJAX URL that would be used to request an Azure Blob SAS URL
file.getSasUri = "/Home/GetBlobSasUrl" + "?blobName=" + file.name;

reader.onloadend = (function (theFile) {
returnfunction (e) {
// Once the reader is done reading the file bytes
// We will issue an AJAX call against our service to get the SAS URL
$.ajax({
type: 'GET',
url: theFile.getSasUri,
success: function (res, status, xhr) {
// Called into GetBlobSasUrl to generate the SAS for the required blob
blobSasUrl = xhr.responseText;
// Now we have a SAS url that we will use to upload the image
// Pass in the SAS URL and the ArrayBuffer to be uploaded
uploadImage(blobSasUrl, e.target.result);
},
error: function (res, status, xhr) {
alert("can't get sas from the server");
}
});
};
})(file);

// Read in the image file as an ArrayBuffer. Once done the reader.onloadend event is raised
reader.readAsArrayBuffer(file);
}
}

Sample JQuery Code for accessing Windows Azure Table

Please refer to the sample code provided in here for JQuery code for InsertEntity and QueryEntities code. A starting point would be the InsertTableEntities.cshtml and QueryTableEntities.cshtml files.

CORS Sample Code

The CORS code sample can be found in here. Please ensure that you have the latest version of the NuGet Package Manager installed in order to get access to the referenced libraries.

The sample by default is configured to use the Windows Azure Storage Emulator which can be downloaded from here. You can use your Windows Azure Storage account by configuring AzureCommon.StorageAccount as part of the AzureCommon.cs file.

Summary

To summarize, the support for CORS in Windows Azure Storage allows application developers to use scripts in their web pages to directly communicate with Windows Azure storage resources (blobs, tables and queues) without having to proxy the calls through their web service. The Windows Azure Storage Client Library makes it simple to configure CORS.

Wael Abdelghani and Jean Ghanem


 

 Resources

CORS Sample code on MSDN

Windows Azure Storage Release - Introducing CORS, JSON, Minute Metrics, and More

2013-08-15 Storage REST version release notes

Cross-Origin Resource Sharing (CORS) Support for the Windows Azure Storage Services

Windows Azure Storage Libraries

 

Windows Azure Storage Explorers (2014)

$
0
0

Users of Windows Azure Storage frequently want to be able to view their data in an “explorer” – a tool that is meant to show the data in a storage account. We have previously made available a list of storage explorers that we are aware of. In this post, we update that list to reflect recent changes. Please note that in this list, we wanted to include tools which are still being actively developed, and so we are only including tools which have been updated in 2012 or later.

As with the previous list, we have not verified the functionality or quality claimed by these utilities and their listing does not imply an endorsement by Microsoft.

The table below is a snapshot of what we are currently aware of and these tools may continue to evolve and grow in functionality. If there are corrections or updates, please leave a comment to let us know. The same is true if you know of tools that ought to be here - we’d be happy to add them.

In the below table, we list each Windows Azure Storage explorer, and then put an “X” in each block if it provides the ability to either enumerate and/or access the data abstraction. The last column indicates if the explorer is free or not. “Trial” indicates that there is a free trial, but the full product is not free. “Y/N” indicates that a version is available for free, while a different version is available for purchase.

(Table updated on 3/4/2014)

Windows Azure Storage
Explorer

Block Blob

Page Blob

Tables

Queues

Free?

Azure Storage Explorer

X

X

X

X

Y

Azure Web Storage Explorer

X

X

X

X

Y

BestSync

X

    

Cerebrata Azure Management Studio

X

X

X

X

Trial

Cloud Berry Explorer

X

X

  

Y/N

Cloud Combine

X

   

Trial

Clumsy Leaf AzureXplorer, TableXplorer, and CloudXplorer

X

X

X

X

Trial

Gladinet Cloud Drive

X

   

Y

Windows Azure SDK Storage Explorer for Visual Studio 2013 (Developed by Microsoft)

X

X

X

 

Y

Zudio

X

X

X

X

Trial

Jeff Irwin
Program Manager
Windows Azure Storage

AzCopy – Support for Read Access Geo-Redundant account

$
0
0

We are glad to announce that AzCopy new version V2.3 has been released at aka.ms/AzCopy.This new version will take advantage of the new Read Access Geo Redundant Storage (RA-GRS) functionality and include support for reading Geo-Redundant account’s data in the secondary region. For RA-GRS, please find details at Windows Azure Storage Redundancy Options and Read Access Geo Redundant Storage.

After enabling RA-GRS in the azure portal, if the primary endpoint is “myaccount.<service>.core.windows.net”, the secondary endpoint will be “myaccount-secondary.<service>.core.windows.net”.

Here are the samples of AzCopy reading blobs from the secondary region (Attention: You cannot copy data to the secondary region).

  • Download blobs from an RA-GRS account’s secondary endpoint to your local disk.

            AzCopy https://myaccount-secondary.blob.core.windows.net/mynewcontainer/ d:\test\ /sourcekey:key /s

  • Copy blob from an RA-GRS account’s secondary endpoint to the primary endpoint.

            AzCopy https://myaccount-secondary.blob.core.windows.net/mynewcontainer/ https://myaccount.blob.core.windows.net/mybackupcontainer/ /sourcekey:key /destkey:key abc.txt

Furthermore, AzCopy V2.3 has made various performance improvements, and has been updated to use Azure Storage Client library v3.0.3.

Zhiming

Microsoft Azure Storage @ BUILD 2014

$
0
0

We were pleased to give an update on Azure Storage at the Microsoft Build conference this year, where we spoke about What’s Coming, Best Practices and described common patterns for making efficient use of Azure Storage. We also summarized our tremendous growth this past year: we are now storing 20+ trillion objects and serving over 2 million requests/second on average.

What’s New?

All Accounts upgraded to 200 TB in capacity and latest Scalability targets

One of the changes we announced is that all storage accounts in production are now upgraded to the latest scalability targets (200TB, 20K request/second) as described here http://msdn.microsoft.com/library/azure/dn249410.aspx.

General Availability of Read-Access Geo Redundant Storage (RA-GRS)

At this time we are pleased to announce the general availability of Microsoft Azure Read-Access Geo Redundant Storage (RA-GRS). RA-GRS allows you to have read access to your date stored in the secondary region, so you can access your data in the event of a failure in your primary storage region. Geo Redundant Storage (GRS) accounts have their data stored in two separate regions. The primary region is what is exposed by default when creating a storage account, and all updates and deletes go to that region.  All updates are then asynchronously geo-replicated to the secondary region.  Enabling RA-GRS for a storage account will allow your application to have eventually consistent read only access to the secondary region’s data in that storage account to provide higher read availability in case the primary is unavailable. For more details, see our earlier blog post on Azure Storage durability options.

Storage Emulator Updates

The release of Storage Emulator 3.0 brings support for the latest REST API version, improved parity with the cloud, and a new scriptable command line interface for starting, stopping, initializing, and clearing the emulator. Storage Emulator 3.0 can be downloaded as part of the Azure SDK 2.3 release for .NET, or as a standalone package. For help using the Storage Emulator, please refer to the MSDN Documentation.

What’s Coming?

We also spoke about a few things that are in the pipeline:

Zone Redundant Storage (ZRS)

Anew redundancy level for Block Blob storage, called Zone Redundant Storage (ZRS) will be made available in the coming months. This new durability offering stores three replicas across multiple zones (facilities) within the same region or across regions (in comparison GRS stores six replicas across two regions – 3 replicas in each region). Pricing details can be found at Microsoft Azure - Innovation, Quality and Price. More details on ZRS to come.

General Availability of the Storage Import / Export Service

The Import/export service provides an efficient solution for importing large amounts of on premise data into Azure Blobs or exporting your Azure Blobs to on premise via shipping disks. This service is currently available in preview and available within US locations. With general availability, we will be announcing more locations in the next few months.

Client Library Updates coming in the next few months

  • .NET– 4.0 release of the .NET library with RTM of WindowsRT and Windows Phone support
  • Java – RTMofJava librarywhich contains new APIs, features, and performance improvements.
  • Android – CTP of Android library
  • C++ - Second release of the Native (C++) library. This release has been updated to leverage Casablanca 2.0 and includes significant performance improvements.
  • Node.js – A new CTP release of the node.js library. This release contains numerous fixes, API enhancements, and full support for the 2013-08-15 REST version.

Finally, for anyone interested in an overview of Azure Storage please take a look at the Introduction to Microsoft Azure Storage post just published.

Windows Azure Storage Team

Microsoft Azure Storage Emulator 3.1 with RA-GRS

$
0
0

We are pleased to announce the release of the Azure Storage Emulator 3.1, with support for Read Access to Geo Redundant Storage (RA-GRS). The read-only replica of the development storage account can now be accessed by using “devstoreaccount1-secondary” in the URL. For example, the following address might be used for accessing a blob using the read-only replica in the storage emulator:

http://127.0.0.1:10000/devstoreaccount1-secondary/mycontainer/myblob.txt

In the Storage Emulator, all accounts have RA-GRS enabled; there is never any lag between the primary and secondary replicas. The Get Blob Service Stats, Get Queue Service Stats, and Get Table Service Stats APIs are supported on the secondary endpoint and will always return LastSyncTime as the current time according to the underlying SQL database.

Starting with Storage Client Library 3.2, the library supports RA-GRS against the storage emulator using the familiar syntax. For example, the following code calls Get Table Service Stats in the emulator:

CloudStorageAccount account = CloudStorageAccount.DevelopmentStorageAccount; 
CloudTableClient client = account.CreateCloudTableClient(); 
 
// Note that Get Service Stats is supported only on secondary endpoint 
client.LocationMode = LocationMode.SecondaryOnly; 
ServiceStats stats = client.GetServiceStats();

Storage Emulator 3.1 is now included in Azure SDK for .NET 2.3. Those who do not currently have SDK 2.3 will get Storage Emulator 3.1 automatically when SDK 2.3 is installed. Those who previously installed SDK 2.3 can upgrade to Storage Emulator 3.1 either by installing SDK 2.3 again or by downloading the standalone installer from the SDK 2.3 download page. Note that Storage Emulator 3.1 is not compatible with SDK versions prior to 2.3.

For more information on Azure Storage Redundancy and RA-GRS, see the blog post on this topic.

Michael Roberson


Introducing Microsoft Azure File Service

$
0
0

 

We are excited to announce the preview of the Microsoft Azure File service. The Azure File service exposes file shares using the standard SMB 2.1 protocol. Applications running in Azure can now easily share files between VMs using standard and familiar file system APIs like ReadFile and WriteFile. In addition, the files can also be accessed at the same time via a REST interface, which opens a variety of hybrid scenarios. Finally, Azure Files is built on the same technology as the Blob, Table, and Queue Services, which means Azure Files is able to leverage the existing availability, durability, scalability, and geo redundancy that is built into our platform.

Scenarios

  • “Lift and Shift” applications

Azure Files makes it easier to “lift and shift” applications to the cloud that use on-premise file shares to share data between parts of the application. To make this happen, each VM connects to the file share (see “Getting Started” below) and then it can read and write files just like it would against an on-premise file share.

  • Shared Application Settings

A common pattern for distributed applications is to have configuration files in a centralized location where they can be accessed from many different virtual machines. Such configuration files can now be stored in an Azure File share, and read by all application instances. These settings can also be managed via the REST interface, which allows worldwide access to the configuration files.

  • Diagnostic Share

An Azure File share can also be used to save diagnostic files like logs, metrics, and crash dumps. Having these available through both the SMB and REST interface allows applications to build or leverage a variety of analysis tools for processing and analyzing the diagnostic data.

  • Dev/Test/Debug

When developers or administrators are working on virtual machines in the cloud, they often need a set of tools or utilities. Installing and distributing these utilities on each virtual machine where they are needed can be a time consuming exercise. With Azure Files, a developer or administrator can store their favorite tools on a file share, which can be easily connected to from any virtual machine.

Getting started

  • Step 1: Sign up for service

To sign up, go to the Microsoft Azure Preview Portal, and sign up for the Microsoft Azure Files service using one or more of your subscriptions. As subscriptions are approved for the Azure File preview, you will get an email notifying you of the approval. We will be slowly opening up the service to users in batches, so please be patient after signing up.

  • Step 2: Create a new storage account

Once you get the approval notification, you can then go to the Microsoft Azure Management Portal and create a new storage account using any of the approved subscriptions. Whenever a new storage account is created for an approved subscription, it will automatically get a file endpoint provisioned. The file endpoint for the account will be: <account name>.file.core.windows.net.

Note, During the Azure File preview, existing storage accounts do not have access to Azure Files. You have to create a new storage account to access Azure Files.

  • Step 3: Create the File Share

You can now create a file share in either of the following two ways:

       ▪ PowerShell CmdLets

Once you download the PowerShell Cmdlets, you can start PowerShell prompt and execute the following:

# go to the directory and you may need to unblock the cmdlet using the following command:
unblock-file .\Microsoft.WindowsAzure.Commands.Storage.File.dll     
 
# import module and create a context for account and key
import-module .\AzureStorageFile.psd1
$ctx=New-AzureStorageContext <account name><account key>
 
# create a new share
$s = New-AzureStorageShare <share name> -Context $ctx
 
# create a directory in the test share just created
New-AzureStorageDirectory -Share $s -Path testdir
 
# upload a local file to the testdir directory just created
Set-AzureStorageFileContent -Share $s -Source D:\upload\testfile.txt -Path testdir
 
# list out the files and subdirectories in a directory
Get-AzureStorageFile -Share $s -Path testdir
 
# download files from azure storage file service
Get-AzureStorageFileContent -Share $s -Path testdir/testfile.txt -Destination D:\download
 
# remove files from azure storage file service
Remove-AzureStorageFile -Share $s -Path testdir/testfile.txt 

       ▪ REST APIs

You can also create a file share programmatically using the ‘Create Share’ REST API with version 2014-02-14 REST APIs are available via http(s)://<account name>.file.core.windows.net Uri. In addition, the .NET Storage Client Library starting with 4.0 version uses the REST version 2014-02-14 and supports Azure Files. We recommend adding a NuGet reference to your project. Here is an abstract of code that creates a share:

staticvoid Main(string[] args)
{
     CloudStorageAccount account = CloudStorageAccount.Parse(cxnString);
     CloudFileClient client = account.CreateCloudFileClient();
     CloudFileShare share = client.GetShareReference("bar");
     share.CreateIfNotExistsAsync().Wait();
}
  • Step 4: Use File Share

Once your share is created, it can be accessed via the SMB or REST protocol from any Azure node (VM/Worker/Web role) hosted in the same region as the storage account hosting the share.

To use the share via SMB 2.1 protocol, log into the VM that requires access to the share and execute “net use” as shown below:

    net use z: \\<account name>.file.core.windows.net\<share name> /u:<account name> <account key>

C:\>net use z: \\myaccount.file.core.windows.net\myshare /u:myaccount StgAccKey==
The command completed successfully.

C:\>dir z:\
Volume in drive Z has no label.
Volume Serial Number is 4038-F841

Directory of z:\

08/06/2013 10:51 AM 15 HelloFromWindosAzureFileService.txt
1 File(s) 15 bytes
0 Dir(s) 109,951,162,777,600 bytes free

C:\>type z:\HelloFromWindowsAzureFileService.txt
Hello World

To remove the mapping of the share from our VM, use: net use z: /delete.

How can I move my data to Azure Files

Azure Files is a separate service from Azure Blobs. In preview, we do not support copying Azure Blobs to Azure Files. In addition, the Microsoft Azure Import/Export Service does not support Azure Files for preview. Both these are in the roadmap and we will share more details in the future.

For preview, the below are the list of options available to transfer files from on premise to Azure File service.

net use z: \\<account name>.file.core.windows.net\<share name> /u:<account name> <account key>

AzCopy

AzCopy version 2.4 now supports moving your local files to Azure files and back. Once your data is in Azure Files, you can easily access this file share from any cloud VM within the same region via SMB protocol.

Assuming you have created a share called “myfileshare” in your file service, here are some examples:

  • Upload files from your local disk recursively to Azure Files, with all folder structures copied as well.

             AzCopy d:\test\ https://myaccount.file.core.windows.net/myfileshare/ /DestKey:key /s

             Note: empty folders will not be uploaded.

  • Upload files with certain file pattern from your local disk to Azure Files.

             AzCopy d:\test\ https://myaccount.file.core.windows.net/myfileshare/ /DestKey:key ab* /s

  • Download all files in the file share recursively to local disk, with all folder structures copied as well.

              AzCopy https://myaccount.file.core.windows.net/myfileshare/ d:\test\ /SourceKey:key /s

             Note: empty folders will not be downloaded.

  • Download one file from the file share to your local disk

             AzCopy https://myaccount.file.core.windows.net/myfileshare/myfolder1/ d:\test\ /SourceKey:key abc.txt

            Note: when specifying the file pattern ‘abc.txt’, AzCopy will try to find exactly the same name file under ‘myfileshare/myfolder1’, not including its subfolders.

The below scenarios are NOT supported in AzCopy during preview.

  • Copying files between Azure Blobs and Azure Files, as well as between Azure File shares.
  • Reading Azure File data from Geo Redundant Account’s Secondary Region.
  • Using Share Access Signature (SAS) to connect with Azure Files.

Storage Client Library 4.0 (or REST APIs version 2014-02-14)

Storage Client library 4.0 supports files and you can write a quick application to upload files into the service.

Remote desktop to the VM which has mapped the share

Using file explorer: There are two ways to copy files using file explorer.

        a. Copy and paste files from your local machine into the file share in explorer in a remote session.

        b. Using xcopy with local drives shared in a remote session

                 i. Remote desktop into an Azure VM and opt to choose the local drive to be accessible in remote session as shown in the below picture.

                     image

                 ii. Create a mapping to the Azure file share using net use as we mentioned above.

                 iii. Use xcopy:

                       xcopy \\tsclient\c\software\demo\data\* \\<accountname>.file.core.windows.net\myshare\data\.

Interaction between SMB and REST Interfaces

As mentioned above, an Azure File share can be accessed via two interfaces at the same time – SMB 2.1 or REST.

When a REST operation is performed on a file that is concurrently open on an SMB client, the REST operation must respect the share mode specified by the SMB client.

This section briefly describes how the two interfaces interact but more details can be found in the MSDN documentation.

The following SMB file access mode is used to determine whether the REST operation can be completed:

REST OperationREST Operation File Access EquivalentComments
List FilesN/A 
Create FileWrite/DeleteIf file is currently open in SMB, can only create the file via REST if the file has write or write/delete share mode.
Get FileReadIf file is currently open in SMB, can only read the file via REST if the file is open with shared read.
Set File PropertiesWriteIf file is currently open in SMB, can only set the file properties via REST if the file is open with Write sharing
Get File PropertiesN/A 
Set File MetadataWriteIf file is currently open in SMB, can only set the file metadata via REST if file is open with Write sharing.
Get File MetadataN/A 
Delete FileDeleteIf file is currently open in SMB, can only delete the file via REST if file is open with Delete sharing.
Put RangeWriteIf file is currently open in SMB, can only write data against the file via REST if file is open with Write sharing.
List RangesReadIf file is currently open in SMB, can only list its ranges via REST if the file if file is open with Read sharing.

NOTE: List Files (REST API), Get File Properties (REST API), and Get File Metadata (REST API) do not operate on SMB file content and do not require read access to the file (i.e. these operations will still succeed even if an SMB client has the file open for exclusive read access).

Here is an example of a sharing violation for REST Get File:

  • An SMB Client opens a file with FileShare.Write (but not FileShare.Read which would mean other clients are not allowed to read the file at the same time).
  • A REST Client then performs a Get File (REST API) operation on the file (thereby using FileAccess.Read as specified in the table above).
  • Result: The REST Client’s request fails with status code 409 (Conflict) and error code SharingViolation since SMB Client still has the file open while denying Read/Delete access).

When to use Azure Files vs Azure Blobs vs Azure Disks

We have three main ways to store data in the Azure cloud – Files, Blobs and Disks. All three abstractions take advantage of Azure Storage stack and the Azure platform. The following section compares the advantages of each abstraction.

Azure Files: Provides a SMB 2.1 interface in addition to the REST interface to provide access to files. The SMB interface enables applications running in the cloud to use native file system APIs to read and write from files. A file share is best for:

  • Lifting & shifting applications to the cloud which already use native file system APIs to share data between pieces of the applications
  • Storing development and debugging tools that need to be accessed from many cloud instances
  • Applications that want REST access to data from anywhere and SMB access to data from within the region the storage account is located in

Azure Blobs: Provides a REST interface for massively scale out object storage.

  • Applications can be written to use REST APIs to store unstructured data into Azure blobs at a massive scale (a single container can be 500TBs in size). .
  • Supports streaming scenarios and random access
  • Access to data from anywhere via REST

Azure Disks: Provides persistent disks to be attached to Azure virtual machine in which data is made durable by storing the disk as a fixed formatted VHD in a page blob in Azure storage. When used as a VHD, the disk can be attached to a single VM, but not shared across VM instances.

  • Lift & Shift applications that use native file system APIs to read and write data to persistent disks, but does not require this data to be available to other cloud VMs. Note that a single disk can be attached to only a single VM at any given time.
  • Individual data stored on the disk is not required to be accessed from outside the VM as the data is stored in a VHD formatted with NTFS. However, the VHD can be downloaded from anywhere via REST API and then loaded onto a local virtual machine.
  • Disks can be snapshotted to create point in time read-only backups. When recovery needs to take place, a snapshot can then be copied to a different blob and data can be recovered.

When accessing Azure Files via SMB 2.1, the share is available to VMswithin the same region as the storage account. The REST interface on other hand is available from everywhere. This new service enables customers to “lift and shift” legacy applications that rely on file system APIs to the cloud without code change.

The following table compares Azure Files with Azure Blobs. The most significant difference is that Azure Files can be accessed via standard file system APIs from VMs (e.g, Azure Files has true directories and supports file and directory rename). Both Files and Blobs provide a REST APIs that allows global access to the data they store. Another important difference is that Azure Blobs scale massively, up allowing up to 500 TB per container, whereas Azure Files limits capacity to 5 TB per share. Finally, Azure Blobs supports the “copy blob”, and “snapshots” APIs, while the preview of Azure Files does not support those APIs.

DescriptionAzure BlobsAzure Files
Durability
Options
LRS, ZRS, GRS (and RA-GRS for higher availability)LRS, GRS
AccessibilityREST APIsSMB 2.1 (standard file system APIs)
REST APIs
ConnectivityREST – WorldwideSMB 2.1 - Within region
REST – Worldwide
Endpointshttp://myaccount.blob.core.windows.net/mycontainer/myblob\\myaccount.file.core.windows.net\myshare\myfile.txt http://myaccount.file.core.windows.net/myshare/myfile.txt
DirectoriesFlat namespace however prefix listing can simulate virtual directoriesTrue directory objects
Case Sensitivity of NamesCase sensitiveCase insensitive, but case preserving
CapacityUp to 500TB containers5TB file shares
ThroughputUp to 60 MB/s per blobUp to 60 MB/s per share
Object sizeUp to 1 TB/blobUp to 1 TB/file
Billed capacityBased on bytes writtenBased on file size

Azure Files complement Azure Disks, which can be attached to Azure VMs. A disk can be attached only to a single VM at any given time. Azure disks are fixed format VHDs stored as page blobs in Azure Storage and are used by the VM to persist the data on the disks. However, a disk is an NTFS formatted VHD (or other file system format) and thus it can be accessed from only a single VM. Also, disks do not have a REST interface that understands the VHD or file system format, and thus you cannot access the data (files) within VHD from outside the VM via REST. File shares based on Azure Files can be access from an Azure VM in the same way they access the local disk. In addition, the file share can be shared across many VMs as well as accessible through REST APIs. The below table highlights some of the differences between Azure Disks and Files.

DescriptionDiskAzure Files
Relationship with Azure VMsRequired for booting (OS Disk) 
ScopeExclusive/Isolated to a single VMShared access across multiple VMs
Snapshots and CopyYesNo
ConfigurationConfigured via portal/Management APIs and available at boot timeConnect after boot (via net use on windows)
Built-in authenticationBuilt-in authenticationSet up authentication on net use
CleanupResources can be cleaned up with VM if neededManually via standard file APIs or REST APIs
Access via RESTCan only access as fixed formatted VHD (single blob) via REST. Files stored in VHD cannot be accessed via REST.Individual files stored in share are accessible via REST
Max Size1TB Disk5TB File Share 1TB file within share
Max 8KB IOps500 IOps1000 IOps
ThroughputUp to 60 MB/s per DiskUp to 60 MB/s per File Share

Characteristics and Compatibility of the Azure File service

The following are the preview scalability targets for Azure Files

  • Up to 5TB per share
  • A file can be up to 1 TB
  • Up to 1000 IOPS (of size 8KB) per share
  • Up to 60MBps per share of data transfer for large IOs

The version of SMB protocol supported is SMB 2.1, which is available on Windows clients using Windows 7 or up, Windows Server 2008 R2 or up. For Linux, Ubuntu images available on the Azure IaaS images gallery are known to support SMB 2.1, however any other distribution with SMB2.1 support should also work.

Pricing

Pricing for the new SMB service is here. During preview, the capacity will be charged at 50% of the GA price.

SMB Compatibility

The SMB 2.1 protocol has many features; some of them are not applicable to the cloud (e.g, named pipes, etc), while others are used so rarely that we do not support them (alternative data streams). Please see here for the list of these features not supported by Azure Storage Files.

FAQ

1. Is SMB 3.0 supported?

We currently support SMB 2.1. We do have it in our list of feature requests to support SMB 3.0 but we do not have a timeline to share yet. We found that SMB 2.1 worked well with most popular systems and tools.

2. Is Active Directory based authentication supported?

We currently do not support AD based authentication or ACLs but do have it in our list of feature requests to support it. For now, the Azure Storage account keys are used to provide authentication and authorized access to the file share.

3. Would a File Share be accessible from outside the region that hosts the storage account?

SMB 2.1 protocol is available only from within the same region as storage account. REST APIs are available for accessing these files concurrently from anywhere.

4. How do I make the share visible to my VM?

You map (or mount) the share as you would any other SMB share in your OS. For Windows, you can use the “net use” command on the command-line, or use the File Explorer to mount a share. The storage account name is the username, and the password is the storage account key:

net use * \\myaccountname.file.core.windows.net\<sharename> /u:myaccountname StorageAccountKeyEndingIn==

5. Can I mount a share from Linux?

Yes. Today, it looks like only the latest 2 Ubuntu images in the portal can support Azure Files. To mount the share from linux, you first need to install some client tools. One choice is cifs-utils. This is the command from Ubuntu to install cifs-utils:

     sudo apt-get install cifs-utils

        Next, you need to make a mount point (mkdir mymountpoint), and then issue the mount command that is similar to this:

     sudo mount -t cifs //myaccountname.file.core.windows.net/mysharename ./mymountpoint -o vers=2.1,username=myaccountname,password=StorageAccountKeyEndingIn==,dir_mode=0777,file_mode=0777

        You can also add settings in your /etc/fstab to mount the share.

6. How do I access the data on the share?

Once the share is mounted, accessing it is no different than accessing any file on your local hard drive. Just use the standard file system APIs to create/open/read/modify/delete the files or directories you need.

7. How do I install the PowerShell Cmdlets for Files?

To work with Azure file service in PowerShell, you first need to download and install the preview module following these steps:

  1. Download the zip format package and unzip it.
  2. Copy the AzureStorageFile folder to %UserProfile%\Documents\WindowsPowerShell\Modules. You need to create this path if it doesn’t exist yet.

     Note:  You could also put this module folder in any other directory but need to make sure the directory path is added to $env: PSModulePath variable. Find more information here.

  1. Double-click the shortcut to open up a PowerShell console with AzureStorageFile module automatically loaded. You could also manually import the module by using import-module cmdlet as shown above in a sample.

     Note:  AzureStorageFile module is in preview and developed on a new version of storage client library which is different from Microsoft azure module. Please import them in different PowerShell sessions. These will be unified in a future SDK release.

8. Does the new emulator support Azure Files?

The new emulator does not support SMB or REST APIs for Azure Files.

Summary and Links

To summarize, we are very excited to announce a new file sharing PaaS service that enables our users to easily share data between application instances using standard file system APIs. As we always do, we would love to hear feedback via comments on this blog, MSDN forum, stackoverflow, or send email to mastoragequestions@microsoft.com.

Please see these links for more information:

Azure Files 2014-04-14 version

AzCopy

Azure File PowerShell Cmdlets (CTP)

Storage .NET Client Library 4.0 for 2014-04-14 version

Brad Calder, Andrew Edwards, Jai Haridas, Atul Sikaria and Jean Ghanem

Announcing Microsoft Azure Import/Export Service GA

$
0
0

 

We are pleased to announce the GA Release of Microsoft Azure Import/Export service!

The preview release has been available in U.S. since November of 2013. We have made improvements to the existing features and also incorporated new features based on working with our preview customers.

In this blog post, we will walk you through information regarding new features in GA, high level capabilities, getting started and when to use this service.

What is New in GA?

We added several key features and improvements in GA release.

  • Available in more regions: In addition to being available in U.S. during preview, the service is now available in Europe and Asia Pacific. Customers who have storage accounts in any of the supported regions can ship the packages to the data center within those regions to import/export their data. There is a section later in this blog which explains more about supported regions and shipping details.
  • Available to all customers: We no longer require customers to obtain a token from us to use the service. Anyone who has a storage account in one of the supported regions will be able to use it.
  • Support for more hardware interfaces: During preview, we officially supported only SATA II drives. We now officially support both SATA II and III drive interfaces.
  • Convenience in return shipping: We can now bill to the customer’s carrier account number for return shipping. The customer needs to provide an account number from one of the supported carrier. This option enables customers to continue enjoy savings on shipping services, if they already have discounted pricing with a carrier.
  • Enhanced tooling: We made several improvements in WAImportExport tool to provide better customer experience:
    • We officially support three USB to SATA converters but incorporated several improvement in making the tool work with the majority of non-supported converters. This allows customers to try out the convertors that they already have to see if it works with the tool before purchasing one of the three supported converters.
    • Using the WAImportExport tool, customers can calculate the number of hard drives based on the available drive size and the amount of data that customers want to export.
    • The WAImportExport tool now provides more precise error messages and recovery options. If there is an issue during drive preparation, the tool generates a repair file along with the detailed errors so that the customer can rerun the tool by providing a repair file as an input to repair the errors.

What is Microsoft Azure Import/Export service?

As described in our Getting Started Guide, Microsoft Azure Import/Export enables moving large amounts of data in and out of Microsoft Azure Blobs into your Microsoft Azure Storage account. You can ship TBs of encrypted data in hard disk drives through FedEx to our data center where Microsoft’s high-speed internal network is used to transfer the data to or from your blob storage account.

The following requirements need to be followed:

  1. The devices need to be up to 4TB 3.5 inch SATA II/III internal hard drives. However, if you prefer USB devices, one of the recommended converters listed in below table can be used to transfer data in/out of SATA from/to USB devices prior to sending or after receiving the drives.
  2. Drives shipped require to be encrypted using BitLocker key.

To make drive preparation easy, we have provided a tool called WAImportExport.exe. More information on how to use the tool can be found here. Once the drives are prepared, you can login into Microsoft Azure Management Portal to

  1. Create Import/Export jobs
  2. Obtain the shipping address to the data center
  3. Update the job with tracking numbers once the drives are shipped using a supported carrier to the location provided in step 2 above
  4. Manage the import/export jobs and monitor progress
  5. Optional step: If there is a failure during an import/export process, the customer can use WAImportExport tool to repair the job.

The following MSDN article talks in depth about the steps involved and also answers some of the frequently asked questions. In addition to the management portal, you can also use the REST interface to create or manage your import/export jobs.

Management Interface

Users can choose one of the following methods to interface with Microsoft Azure Import/Export service:

  1. Microsoft Azure Management Portal Interface to manage jobs
  2. REST Interface

Encryption

Mandatory requirement to encrypt data in the drive with a BitLocker key

Supported Device

3.5 inch SATA II/III hard drives

Note: You can easily transfer your data via USB to a SATA II/III drive by using one of the SATA to USB adaptors:

1. Anker 68UPSATAA-02BU

2. Anker 68UPSHHDS-BU

3. Startech SATADOCK22UE

Supported Maximum Disk Capacity

4 TB

Maximum Number of Jobs per Storage Account

20

Maximum number of drives per job

10

Supported file format

NTFS

Table 1 Quick requirement overview

When to use Microsoft Azure Import/Export Service?

Large data sets take very long time to upload or download over the network. 10 TB takes 2 years over T1 (1.5Mbps) or 1 month over T3 (44.7 Mbps). Customers can ship the drive using Microsoft Azure Import/Export service and significantly cut down the data upload or download time. The Microsoft Azure Import/Export service can take up to several days in addition to shipping as against weeks or months using a T1 or T3 link.

If you have TB’s of data, Microsoft Azure Import/Export can move data in and out of Microsoft Azure blobs much faster than uploading and downloading data over the Internet.

The factors that come into play when choosing are:

  1. How much data needs to be imported/exported?
  2. What is network bandwidth to the region I want to copy data into or from?
  3. What is cost of bandwidth?

Customers can calculate the time it would take over their network. If it is less than several days and the import/export service is available for their region, then they should choose Microsoft Azure Import/Export service. However, for customers already having good peering or for smaller amounts of data, Microsoft Azure Copy tool described here can be used to import/export data from/to on premise.

Regions Supported

The service supports importing data to and exporting data from storage accounts in the following regions:

  • East US
  • West US
  • North Central US
  • South Central US
  • North Europe
  • West Europe
  • East Asia
  • Southeast Asia

If you have a storage account in one of the supported regions, you will ship your drive to the physical location of your storage account. Our service will provide you a shipping address to ship your package upon successful creation of an import/export job.

You must follow the following important legal disclaimer when shipping cross international borders.

Please note that the physical media that you are shipping may need to cross international borders. You are responsible for ensuring the physical media and data are permitted to be imported and/or exported in accordance with the applicable laws. Before shipping the physical media, check with your advisors to ensure the media and data can be shipped to the identified data center to help ensure that it reaches us in a timely manner.

For instance, if your storage account resides in an European data center but you are shipping your package from U.S., it is your responsibility to ensure that you comply with all the applicable laws and complete all necessary forms to ship your package from U.S. to EU to avoid any delays. Microsoft is not responsible and will not engage with authorities to retrieve your package.

Pricing

The Microsoft Azure Import/Export service will charge a drive handling fees of $80 per drive.

Regular storage transactions charges will apply for putting (import) and getting (export) the blobs from your storage account.

For import jobs, there is no ingress charge for the copy operation.

More details on pricing can be found here.

Summary

We are continuously making improvements to make this service better and very much value your feedback. Please feel free to leave comments and questions below or send an email to waimportexport@microsoft.com.

Please make sure to review legal supplemental terms of use and Microsoft Azure Services Terms for Microsoft Azure Import/Export Service prior to using this service.

Aung Oo, Jai Haridas, Pradnya Khadapkar and Brad Calder

Resources

Getting Started guide

Download WAImportExport.exe tool

WAImportExport.exe guide

Microsoft Azure Import/Export Service REST interface

Pricing details

Microsoft Azure Copy tool

Microsoft Azure Services Terms

Supplemental Terms of Use for Microsoft Azure Previews and Microsoft Azure Import/Export Service

What’s new for Microsoft Azure Storage at TechEd 2014

$
0
0

At TechEd, we introduced a number of exciting changes in addition to release of a new service which is first of its kind amongst all cloud service providers. If you missed the talk on Azure Storage service at TechEd, you can view it here. Here is a brief list of things we spoke about:

  1. A new service called Azure Files
  2. Increase in storage capacity limits to 500 TB per storage account for existing and new accounts.
  3. Increase in storage bandwidth limits to 10 Gibps Ingress and 30 Gibps Egress per storage account located only in U.S regions for existing and new accounts.
  4. General availability of our Import/Export Service
  5. A new REST version 2014-02-14 that includes Azure Files and a new Shared Access Signature (SAS) feature that allows users to control the REST protocol version used to process the request independent of the SAS token version.

We are also releasing an updated Microsoft Azure Storage Client Library 4.0 here that supports the features listed above and can be used to exercise the new features. In addition, a new version of the Storage Emulator 3.2 can be found in here that supports the new Storage version for Azure Blob, Azure Table and Azure Queue. Note that the emulator does not support Azure Files.

Introducing Microsoft Azure Files

Microsoft Azure Files provides a file share in the cloud via SMB 2.1 protocol. This file share can be used by applications in the cloud to share files between VM instances within a same region. In addition, it provides a REST interface for the file share to be accessed from anywhere at the same time the files are being accessed by VMs via SMB. More details can be found at in this blob and this MSDN page.

Increase in storage limits

All storage accounts in all regions now get 500 TB capacity per storage account.

In addition we have increased the bandwidth limits for storage accounts located in US regions to the following:

For Geo Redundant Storage (GRS) Accounts

  • Ingress=10 Gibps
  • Egress=20 Gibps

For Local Redundant Storage (LRS) Accounts

  • Ingress=20 Gibps
  • Egress=30 Gibps

Bandwidth per storage accounts in other regions remains unchanged. More details in here.

General Availability of our Import/Export service

Our import/export service is exiting preview and now available in Europe and Asia Pacific regions too. Customers need not apply for tokens and can now import/export data from/to storage accounts by shipping disks. More details can be found at this blog post.

Changes in Shared Access Signatures (SAS)

Before we go into more details about the change, we will briefly describe the versioning scheme in Azure Storage and what Shared Access Signature (SAS) is.

Shared Access Signature

Shared Access Signatures (SAS) are pre-authenticated tokens with which clients can provide access to intended storage resources with specific permissions and without having to share their secret keys. This authentication model is very useful for scenarios like mobile applications, services that require access to storage resources but cannot store secret keys because of security or compliance. Owner of storage resource can control the following parameters while creating a SAS token:

  1. The resources that user can access using the token
  2. The start and end time for access
  3. The permissions (like read/write etc.) allowed

Anyone who has the SAS token can access the resources allowed with the provided permissions on the resource(s). More information can be found in this MSDN page.

Applications typically use a single REST version to perform their REST calls to Azure Storage. The storage service introduces a new version whenever new service features are added or breaking changes (syntax or semantics) in the protocol occur. Applications can control the REST version via the x-ms-version header. However for SAS, the query parameter sv is used as the SAS authentication version and as the request processing version. It is worth noting that sv is determined by the application generating the SAS token. This could be a problem when clients using SAS token to access storage resources may want a different version than the one specified in sv.

Example:https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list&sv=2013-08-11&si=readpolicy&sig=a39 %2BYozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ%3d

Changes in 2014-02-14 version

As mentioned before, SAS token specifies an sv query parameter which decides the version used for interpreting the SAS parameters and the REST protocol. This introduces a problem for applications in which a service generating the SAS token and client service consuming the SAS token version use different versions of storage REST APIs.

To resolve this issue, we have decoupled the versioning of a SAS token from the REST protocol version. Starting in version 2014-02-14 (i.e. sv=2014-02-14), we have introduced a new query parameter api-version that can be appended by client applications dependent on SAS tokens to specify which protocol version that storage service should use to process the request.

Example:https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list&sv=2014-02-14&si=readpolicy&sig=a39 %2BYozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ%3d&api-version="2012-02-12"

Hence these are the different parameters that control versioning in a URL to a SAS protected resource:

  • SignedVersion (sv) query parameter within a SAS token that defines the SAS version to use for authentication and authorization and interpret any SAS parameter that impacts authentication or authorization. This is what SAS generators would set.
  • API version (api-version) query parameter to define the REST protocol version to use. Client applications using SAS token should set this value to lock to a given storage service version.

More information can be found here in MSDN.

Examples:

Let’s use the ListBlobs API as an example to see how the version is interpreted. ListBlobs protocol changed starting with 2013-08-11 in which the Uri of the blob was removed from the protocol body. Client library for versions before 2013-08-11 expected this Uri to be present.

Using SAS version 2014-02-14, here are two possible scenario that can occur, controlled by the consumer of the SAS token.

  • List Blobs using sv=2014-02-14 version and no api-version override.

https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list&sv=2014-02-14&si=readpolicy&sig=a39 %2BYozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ%3d

In here, the service will authenticate and authorize access using 2014-02-14 SAS version and will also execute the API using the same 2014-02-14 for the protocol.

  • List Blobs using sv=2014-02-14 version and api-version override.

https://myaccount.blob.core.windows.net/mycontainer?restype=container&comp=list&sv=2014-02-14&si=readpolicy&sig=a39 %2BYozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ%3d&api-version=2013-08-11

Here, the service will authenticate and authorize using 2014-02-14 version and execute the API using 2013-08-11 of the protocol. Hence clients using Storage client library versioned 2013-08-11 will work.

Best Practices

For generating SAS tokens, the recommendation would be to use the Storage Client library 4.0 or later for generating the SAS tokens and return the token as is to clients like the below code snippet:

CloudStorageAccount account = CloudStorageAccount.Parse(cxnString);
CloudBlobClient blobClient = account.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("demo");
CloudBlockBlob blob = container.GetBlockBlobReference("phot.jpg");
string sasToken = blob.GetSharedAccessSignature(
new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write,
SharedAccessExpiryTime = DateTime.UtcNow.AddDays(1)
});

// return the token as is or if it is Uri needs to be handed out then
// return blob.Uri.AbsoluteUri + sasToken;
return sasToken;

For SAS Consumers, the recommendations are as follow:

  • For applications using Storage client library 2.0 and above: client libraries will just work when client applications are using SAS tokens that have sv set to 2014-02-14 or later.
  • For applications building their own REST protocol implementation: When a token with sv is set to version 2014-02-14 or later, you can append api-version query parameter and set it to the needed version.

Please do use this version and provide us feedback via comments on this blob, MSDN forum or stackoverflow.

Microsoft Azure Storage Team

Resources

Microsoft Azure Files MSDN documentation

MSDN release notes for version 2014-04-14

Introducing Microsoft Azure File Service

Announcing Microsoft Azure Import/Export Service GA

Shared Access Signatures

Storage .NET Client Library 4.0 for 2014-04-14 version

Microsoft Azure Storage Emulator 3.2.

Microsoft Azure Storage Client Library and Tooling Updates @ TechEd 2014

$
0
0

Continuing our recent updates from TechEd, we are pleased to announce a number of updates and additions to our client libraries and tools.

Client Libraries

Java 1.0 – RTM Update

Java was our first language supported outside of .NET. We have continued to update and improve it since its initial release, to keep up with new service versions and respond to your feedback. We are now releasing version 1.0 of our Java library, and officially labeling it “RTM”, meaning it is ready for use in your production applications. The 1.0 version uses the 2014-02-14 version of our REST API, which is discussed more fully in this blog post. This library does not yet support the new Azure Files service – this will be supported in an update coming soon. You can get the 1.0 Java client library from GitHub or Maven.

Android 0.1 – New Preview

We are excited to release version 0.1 of our Android library, which uses the 2014-02-14 version of our REST API. This library is a preview, but will be actively updated going forward (including adding support for the Files API). Android developers may find our “Getting Started” docs for Java useful (Blobs, Tables, and Queues). The library itself is available on GitHub or Maven.

.NET 4.0 – Files support and Deprecation of WCF Data Services Table Layer

We are also releasing an update to our .NET client library. This client library supports the Files service, and uses the new 2014-02-14 REST API version. We also are marking the WCF Data Services-based Table layer as deprecated. We introduced a new, faster table layer in version 2.0 of our .NET library (read about it here) in the fall of 2012. User feedback has informed us that it is much preferred to the old layer, and our performance tests show it is much faster. As a result, we will be removing the older layer in a future release. This will reduce the dependencies for the library going forward and reduce confusion when new users begin using the library. 4.0 includes a new set of helpers for using Azure Storage Analytics, as well, which can be found in the Analytics namespace. These provide a set of methods which simplify the process of retrieving and viewing the information stored by analytics - making it easier to find specific logs in a certain time range or query specific metrics tables. You can get the new 4.0 version of our library on NuGet.

.NET 3.2.1 – Bug Fixes

While we encourage users to move forward to the 4.0 library above, we have also made an update to the 3.2 library to fix a pair of bugs. This library continues to use the 2013-08-15, like the previous 3.x versions, so this update includes no breaking changes from the 3.2 library. You can read about the changes in the change log on GitHub, and can get the library on NuGet.

Windows Phone and Windows Runtime RTM

Now included in the same NuGet package as the .NET 4.0 Client Library are the RTM versions of our libraries for Windows Phone and Windows Runtime. These libraries are now ready for use in your production applications. The previous preview package (3.2.0-preview on NuGet) is now no longer supported.

C++ 0.3 – Preview Update

Last fall, we released a new client library for C++. This week, we are releasing an update, version 0.3. It can be used with the new Storage Emulator 3.2, which supports RA-GRS behavior. And it contains a number of other new features, bug fixes, and performance improvements. See the change log on GitHub for details. The library can be downloaded from NuGet.

Still to come: iOS and Node.js

We also recently announced that iOS and Node.js libraries are coming this year. We’re hard at work, so please stay tuned to this blog for word on their release when they are ready.

Tools

Storage Emulator 3.2

We have released two updates to Storage Emulator recently. 3.1 was released last week, and supported RA-GRS behavior. 3.2 was released this week, and supports the new 2014-02-14 REST version, and associated new versioning behavior. It does not support the new Files service. See the blog post from 3.1 for instructions on how to install this update – the installation steps are the same.

AzCopy 2.4

AzCopy has been updated to support the new Files service. You can read more about it in the blog post about the Files service.

PowerShell

We’ve released a preview snap-in for managing your Files shares using PowerShell. It is further discussed in this blog post about the new Files service.

Conclusion

This is our largest single release of new tools and libraries ever, and we’re excited to be continuing to improve the developer experience when using Azure Storage. All of this is driven by your feedback, so please continue to give us feedback through one of the following

Jeff Irwin

Persisting connections to Microsoft Azure Files

$
0
0

We recently blogged about our preview release of Azure Storage Files here. The post contained information on Azure Files, how to get started by applying for preview and explained some tools that we have to help you create the share and transfer data. This post will concentrate on how you can create a persistent connection to an Azure File share so that after a VM reboots, the share will be available for your scheduled tasks, applications, or logged in user.

Windows IaaS VMs

By default, Windows attempts to persist connections to SMB shares across reboots. However, it will not automatically persist your Azure Files credentials across reboots, so it will fail to reconnect to an Azure Files share after a reboot. There are several ways to persist these credentials, some of which are detailed below.

Persisting Credentials

CmdKey

The easiest way to establish a persistent connections is to save your storage account credentials into windows using the “CmdKey” command line utility. The following is an example command line for persisting your storage account credentials into your VM:

C:\>cmdkey /add:<yourstorageaccountname>.file.core.windows.net /user:<yourstorageaccountname> /pass:<YourStorageAccountKeyWhichEndsIn==>

Note: yourstorageaccountname is not your live id but the name in the endpoint.

CmdKey will also allow you to list the credentials it stored:

C:\>cmdkey /list

Currently stored credentials:

Target: Domain:target=filedemo.file.core.windows.net
Type: Domain Password
User: filedemo

Once the credentials have been persisted, you no longer have to supply them when connecting to your share. Instead you can connect without specifying any credentials:

C:\>net use * \\filedemo.file.core.windows.net\demo1

Drive Z: is now connected to \\filedemo.file.core.windows.net\demo1.

The command completed successfully.

Then you can reboot your VM (this will disconnect you from your VM):

shutdown –t 0 –r

When your VM has restarted and you reconnect, you can open up another command window and confirm that your connection has been automatically reconnected:

C:\>net use

New connections will be remembered.

Status    Local    Remote       Network

-----------------------------------------------------------------------------

OK        Z:       \\filedemo.file.core.windows.net\demo1

                                Microsoft Windows Network

The command completed successfully.

Credential Manager

The credential manager (located under Control Panel\User Accounts) will also allow you to persist your storage account credentials.

image

User Contexts

Windows maintains different contexts for each user that is running on a VM, and sometimes it will have different contexts for the same user on the same VM at the same time. Each context can be independently connected to a different set of SMB shares, and each context will have its own drive letter mapping to the shares it is connected to.

The credentials persisted by CmdKey are available to the user who ran “CmdKey”. The connections remembered by “net use” are also available to the user who ran net use. Therefore, if you have an application that runs under a different user name, you may want to persist the credentials and connections for other user’s as well. To do that, you can use the “runas” command:

runas /user:<username> cmd.exe

That command will open a new command window. The title of the command window will read “cmd.exe (running as COMPUTERNAME\username)”. If you run “net use” in that command window, you will notice this user is not connected to any shares:

C:\>net use

New connections will be remembered.

There are no entries in the list.

You can run “CmdKey” and “net use” as above for that user, and persist both your storage credentials and connections to Azure File for that user.

Administrator Contexts

If you create a new local user on your VM, and add that user to the administrators group, then you can run commands for that user in both elevated and non-elevated contexts. Connections are not shared between elevated and non-elevated contexts, so you may want to connect separately in each context by executing “net use”. However, the persisted credentials are shared, so you only need to run “CmdKey” in one of the contexts.

Handling Scheduled Tasks

You can create scheduled tasks that run under any user on the VM, and credentials persistent with CmdKey for that user will be available to the schedule tasks. However, those scheduled tasks may run in a different user context than the logged in user, so connections to SMB shares will not be automatically re-connected in the user context that the task is running under.

For example, if you created a schedule task that runs a script that calls “net use” and writes the output to a local file, and that user had previously created a persistent connection to an Azure File share and also had persistent the credentials for that share, the output would contain:

Status      Local    Remote       Network

-----------------------------------------------------------------------------

Unavailable Z:       \\filedemo.file.core.windows.net\demo1

                                  Microsoft Windows Network

The command completed successfully.

However, the credentials are available in that context to reconnect to the share, so adding the following command to your script will re-establish the network connection:

net use z: \\filedemo.file.core.windows.net\demo1

Alternatively, the script can access files using the full UNC path rather than the mapped drive letter:

dir \\filedemo.file.core.windows.net\demo1

Also note that since the scheduled task is running in a different context that the logged in user, connections created by the schedule task may not be connected for the context of the logged in user.

Windows PaaS Roles

Persistent connections are the opposite of what you want for PaaS roles. For PaaS roles, you need to ensure that your code can connect automatically whether the system has started a fresh instance, or if your instance has just been restart.

PInvoke WNetAddConnection2

You can map a drive letter in your PaaS role startup code by pinvoking WNetAddConnection2. The following code declares a set of structures you need to establish a mapping from an Azure Files share to a local drive letter.

[DllImport("Mpr.dll",
            EntryPoint = "WNetAddConnection2",
            CallingConvention = CallingConvention.Winapi)]
privatestaticexternint WNetAddConnection2(NETRESOURCE lpNetResource,
string lpPassword,
string lpUsername,
                                             System.UInt32 dwFlags);
 
[DllImport("Mpr.dll",
           EntryPoint = "WNetCancelConnection2",
           CallingConvention = CallingConvention.Winapi)]
privatestaticexternint WNetCancelConnection2(string lpName,
                                                System.UInt32 dwFlags,
                                                System.Boolean fForce);
 
[StructLayout(LayoutKind.Sequential)]
privateclass NETRESOURCE
{
publicint dwScope;
public ResourceType dwType;
publicint dwDisplayType;
publicint dwUsage;
publicstring lpLocalName;
publicstring lpRemoteName;
publicstring lpComment;
publicstring lpProvider;
};
 
publicenum ResourceType
{
    RESOURCETYPE_DISK = 1,
};

Then you can write a method that will mount the share on a given drive letter:

publicstaticvoid MountShare(string shareName,
string driveLetterAndColon,
string username,
string password)
{
if (!String.IsNullOrEmpty(driveLetterAndColon))
    {
// Make sure we aren't using this driveLetter for another mapping
        WNetCancelConnection2(driveLetterAndColon, 0, true);
    }
 
    NETRESOURCE nr = new NETRESOURCE();
    nr.dwType = ResourceType.RESOURCETYPE_DISK;
    nr.lpRemoteName = shareName;
    nr.lpLocalName = driveLetterAndColon;
 
int result = WNetAddConnection2(nr, password, username, 0);
 
if (result != 0)
    {
thrownew Exception("WNetAddConnection2 failed with error " + result);
    }
}

Then you can call this method from the “OnStart()” method of your role:

MountShare("\\\\filedemo.file.core.windows.net\\demo1",
"z:",
"filedemo",
"<YourStorageAccountKeyWhichEndsIn==>");

From that point forward in your worker role, you will be able to read and write files to the Azure File share using either the drive letter, or the full UNC path:

File.Create("z:\\WNetAddConnection2.txt");
File.Create(\\\\filedemo.file.core.windows.net\\demo1\\UNC.txt);

Web Roles and User Contexts

The OnStart() method of an Azure Web Role runs in a different user context than is used to render pages of the web site. Therefore, if you want to reference your Azure Files shares from the code that renders the pages, you should put the code from above in your Global.Application_Start() method rather than WebRole.OneStart().

Linux VM

Linux has a variety of methods for automatically mounting shares during startup, but we only experimented with one method, and only on Ubuntu 14.04 LTS.

Persist Connections with Fstab

Linux has a file called “fstab” in /etc that can be used to mount drives and shares during startup. One way to automatically mount an Azure Files share during boot is to add a line to /etc/fstab. The following text should be placed on a single line in the file:

//<yourstorageaccountname>.file.core.windows.net/demo1 /home/azureuser/smb cifs vers=2.1,dir_mode=0777,file_mode=0777,username=<yourstorageaccountname>,password=<YourStorageAccountKeyWhichEndsIn==>

There are several parts of this line, described below in this table:

 

Part

Example

Description

Share URL

//filedemo.file.core.windows.net/demo1

The URL of an Azure Files share that you previously created

Mount point

/home/azureuser/smb

The path to an empty directory on your Linux VM that you previously created where you want the share to be mounted.

File system

Cifs

The type of file system you want to mount. For Azure Files, this will be ‘cifs’.

Mount Parameters

vers=2.1

The version of SMB to use, in this case version 2.1

dir_mode=0777

The permissions mask used for directories in the Azure Files share, in this case full permissions.

file_mode=0777

The permissions mask used for files in the Azure Files share, in this case full permissions.

username=filedemo

For Azure Files, this username needs to be you storage account name.

password=StorageAccountKey==

For Azure Files, this password needs to be your full storage account key.

There are many other options that can be included in your fstab file. For more information see the relevant document for the Linux distribution you are using.

Summary

Our previous post introduced Azure Files and this post concentrates on steps to help you create persistent connections to Azure File shares so that connections to shares are available after a reboot. As always we would love to hear feedback via comments on this blog, Azure Storage MSDN forum, or send email to mastoragequestions@microsoft.com.

Andrew Edwards

Please see these links for more information:

Azure Files 2014-04-14 version

Introducing Microsoft Azure File Service

AzCopy

Azure File PowerShell Cmdlets (CTP)

Storage .NET Client Library 4.0 for 2014-04-14 version

Microsoft Azure Storage Client Module for Node.js v. 0.2.0

$
0
0

The Microsoft Azure Storage team is pleased to announce the CTP release of our first dedicated client library module for Node.js. This new release incorporates significant improvements over the existing node module and will be the Storage client module that is actively developed and supported moving forward. This module contains many improvements in the programming model and architecture, and includes support for the 2014-02-14 REST Storage service version. The list of improvements is long but in summary our 0.2 release includes: support for RA-GRS, expanded Table Payload Protocol support, Table Insert optimization and query helpers, Shared Access Signature support for all services, Maximum Client Execution Timeout etc.

This is currently a CTP release, meaning that this is the best time to give feedback. The source code is available via Github (note the updated location). You can download the package and its dependencies from npm using the following:

npm install azure-storage

 

Samples

For information on setting up the Node.js environment for development, see the Resources section at the bottom of this document. We have also provided a series of Getting Started articles on the Azure Node.js developer center (Blobs, Tables, Queues) and samples on Github to help clients get up and running with Azure Storage and to illustrate some key scenarios.

To run a given sample or test, the connection information for the storage account need to be set up. This can be provided using:

  • Environment variables - AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY, or AZURE_STORAGE_CONNECTION_STRING.
  • Constructors - For example, var tableSvc = azure.createTableService(accountName, accountKey);

In order to be able to use a proxy like fiddler, an additional environment variable should be set up:

HTTP_PROXY

Depending on the platform being used, these can be accomplished using the following:

  • Windows(In command prompt) -
set AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=http;AccountName= ”account name”;AccountKey=”account key”
set HTTP_PROXY= http://127.0.0.1:8888
  • Linux(In shell) –
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=http;AccountName= ”account name”;AccountKey=”account key”
HTTP_PROXY= http://127.0.0.1:8888
  • Mac(Edit the .bashrc or .bash_profile file and add the following lines) –
export AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=http;AccountName= ”account name”;AccountKey=”account key”
export HTTP_PROXY= http://127.0.0.1:8888

Users attempting to develop against the Storage Emulator should make sure they are using Emulator version 3.2 or later that supports 2014-02-14 REST version and should set the environment variable ‘EMULATED’ to true.

The unit tests can be run from the module's root directory using:

npm test

 

A Note about Packaging

We have moved the Storage module out of the Microsoft Azure SDK for Node to its own module. Developers leveraging the existing module will need to update their dependencies accordingly as the previous storage implementation (azure-storage-legacy) will be deprecated in the future and Microsoft Azure SDK for Node will include this module. A migration guide for users moving from the existing module will be made available in the future. To begin using the storage module, install ‘azure-storage’ via npm and add it to your .js file.

var azure = require(‘azure-storage’);

 

What’s New

This Storage Client Module provides support for the 2014-02-14 REST service version, as well as key client side improvements across Blobs, Queues and Tables listed below.

 

Support for Read Access Geo Redundant Storage

This release has full support for Read Access Geo-Redundant Storage (RA-GRS) which allows for reading from the Storage account data in the secondary region. This functionality needs to be enabled via the portal for a given Storage account.

Applications may retrieve the secondary replication status and last sync time for the [Blob|Table|Queue]Service using getServiceStats. Setting the location mode on the service object and invoking getServiceStats is shown in the example below. The locationMode can also be configured on a per request basis by setting it on the options object (options.locationMode). By default, the location mode is set to PRIMARY_ONLY.

var azure = require(‘azure-storage’); 
var blobService = azure.createBlobService(); 
// getServiceStats is supported only on secondary endpoints. 
blobService.defaultLocationMode = 
azure.StorageUtilities.LocationMode.SECONDARY_ONLY; 
blobService.getServiceStats(function (error, serviceStats){ 
if(!error) { 
        Console.log(‘Replication status = %s and LastSyncTime = %s’, serviceStats. 
        GeoReplication.Status, serviceStats.GeoReplication. LastSyncTime); 
    } 
});

 

Expanded Table Protocol Support (JSON)

This release adds support for JSON payloads on the table service. Instead of AtomPub, the default protocol is now JSON minimal metadata. (You can read more details regarding these protocols as well as view sample payloads here). This change dramatically reduces the payload size of the request and the CPU required to process it, allowing applications to scale higher and realize lower overall latencies for table operations. The AtomPub protocol is no longer supported by the client. An example of setting the payloadFormat on the service object is shown in the example below. The payloadFormat can also be configured on a per request basis by setting it on the options object.

var azure = require(‘azure-storage’); 
var tableService = azure.createTableService(); 
// Set the payload format to JsonNoMetadata. 
tableService.defaultPayloadFormat = TableUtilities.PayloadFormat.NO_METADATA;

 

In some scenarios, notably when using JsonNoMetadata, clients may wish to provide the property type information at runtime for entities returned by queries. To support this scenario, the user may implement a property resolver which returns the EdmType for each property. The sample below illustrates a propertyResolver implementation.

var propertyResolver = function (pk, rk, name, value) { 
if (name.indexOf('BinaryField') !== -1) { 
return'Edm.Binary'; 
    } elseif (name.indexOf('GuidField') !== -1) { 
return'Edm.Guid'; 
    } elseif (name.indexOf('DateField') !== -1) { 
return'Edm.DateTime'; 
    } elseif (name.indexOf('DoubleField') !== -1) { 
return'Edm.Double'; 
    } 
return'Edm.String'; 
};

 

This propertyResolver is set on the options object as shown below.

options.propertyResolver = propertyResolver; 

Note that due to JavaScript’s inability to differentiate between an int and a double whose decimal part is 0 (5 versus 5.0) while parsing numbers, both of these are returned without the decimal component and a type is not specified. To preserve the type information while round tripping data from the server, please use a property resolver as described above to differentiate between these.

For more information about table queries, please check out the documentation in tableservice.js.

 

 

Table Insert Optimizations

In previous versions, the service would “echo” back the entity content in the response body. With this release all Table Insert operations, including those executed as part of a batch operation, will send the Prefer: return-no-content header to avoid this behavior. This optimization can dramatically reduce latencies for insert operations. Please note that this will cause the resulting HTTP status code on the insertEntityResponse for successful inserts to be 204 (no-content) rather than 201 (Created) and the entity is not returned back in the insertEntityResult object. The echo content behavior can be re-enabled by setting echoContent to true in the options object as shown below:

options.echoContent = true;

 

Table Query Helpers

TableQuery provides helper methods to create filter strings to use with the where clause for a query. Query strings may include type specifiers where necessary. For example, to query on a long value, users could do the following:

var tableQuery = new TableQuery().where(TableQuery.int64Filter('Int64Field', TableUtilities.QueryComparisons.EQUAL, '4294967296'));

OR

var tableQuery = new TableQuery().where('Int64Field == ?int64?', '4294967296');

 

Table Entity Creation Helpers

We have added entity-property-creation helper methods to aid users. Users can use the entityGenerator helper provided in TableUtilities and create entity properties as follows instead of using the more verbose ‘_’ and ‘$’ format:

 
var entGen = TableUtilities.entityGenerator;
var entity = { PartitionKey: entGen.String('part2'),
RowKey: entGen.String('row1'),
boolValueTrue: entGen.Boolean(true),
intValue: entGen.Int32(42),
dateValue: entGen.DateTime(new Date(Date.UTC(2011, 10, 25))),
};

 

We have also removed one additional layer of addressing while adding type information to an entity. A new entity can now be created using:

 

DateValue: { 
_: dateVal, 
$: 'Edm.DateTime'
} 

 

Other notable new features

We have expanded the api surface to add additional conveniences, including:

  • Shared Access Signature support for Containers, Queues and Tables
  • Anonymous Access support for Blobs
  • Leasing support for Containers
  • Ability to set the Maximum Execution Timeout across retries for every API
  • MD5 validation for blob upload/download
  • Table Batch re-design to construct and execute Table Batch requests instead of turning the service batch mode on/off

 

ChangeLog

This release includes several client side changes and features other than the notable ones mentioned above. You can view the complete ChangeLog on Github.

 

What’s next

We are adding support for Files in an upcoming release. You can find more information about the File service support in Azure Storage and sign-up details here.

 

Summary

We are continuously making improvements to the developer experience for Azure Storage and very much value your feedback in the comments section below, the MSDN or StackOverflow forums, or GitHub. If you hit any issues, filing them on GitHub will also allow you to track the resolution.

Veena Udayabhanu, Emily Gerner, Adam Sorrin, and Vinay Shah

 

Resources

Source (Github)

npm

How to Use the Blob Service from Node.js

How to Use the Queue Service from Node.js

How to Use the Table Service from Node.js

Azure Storage Release - Introducing CORS, JSON, Minute Metrics, and More

Azure Tables: Introducing JSON

Azure Storage Redundancy Options and Read Access Geo Redundant Storage

Introduction to Node.js

Install Node.js

Sublime Text Environment

Debugging Node.js applications using node-inspector

(Cross-Post) Migrating Data to Microsoft Azure Files

$
0
0

About Microsoft Azure Files

Microsoft Azure Files is a cloud based storage service that exposes SMB2.1 protocol based file shares in the cloud. Applications running in Azure can now easily share files between VMs using standard and familiar file system APIs like ReadFile and WriteFile. In addition, the files can also be accessed at the same time via a REST interface, which opens a variety of hybrid scenarios. Finally, Azure Files is built on the same technology as the Blob, Table, and Queue Services, which means Azure Files is able to leverage the existing availability, durability, scalability, and geo redundancy that is built into our platform. The service is currently in preview. To read more details about the service, please refer to our blog post on Files.

 

Migrating Data

As you start to use Azure Files, you may need to move large amount of existing data into the Files service. There are many options for moving data efficiently to Azure Files, and which you choose will depend on where the data is originally located. The rest of this post discusses these options, and how to achieve best performance using each option.

1. On-premise to Azure Files over the internet

To copy files, you can use the AzCopy tool provided by Microsoft Azure. AzCopy implements a number of optimizations to ensure best throughput for the copy job (e.g., parallel uploads, multiple threads, correct handling of throttling, etc.).

The format of the AzCopy command line is:

AzCopy <source path> <destination URL> [optional filespec] /S /DestKey:<YourKey>

Where

source path is the path to the directory you want to migrate

destination URL is the http URL to the directory you want to copy to

filespec specifies any file filters for files you want to move (default is *.*)

YourKey is the storage account key for the destination storage account

/S is an optional switch to copy all directories and subdirectories under the source directory

AzCopy has many other command-line options, and you should use any others that make sense for your case. For more information, refer to this blog post on AzCopy.

Here is an example command to copy files in the c:\data directory to Azure Files:

AzCopy c:\data https://myaccount.file.core.windows.net/myshare *.* /S /DestKey:myStorageAccountKey

2. Azure Disk on an IaaS VM to Azure File

Customers who run a File server role on IaaS VMs in Azure are finding the Azure File service very attractive, since it frees them from having to manage a file server themselves

To migrate data from an IaaS disk to a Share, you need to:

  1. Attach the disk to the VM
  2. Mount the share on your VM
  3. Use robocopy to copy the data into the Azure File shares

Robocopy is a free and robust file copy utility included in Windows, for doing large file copies.

The command-line format to use is:

Robocopy<source path> <dest path> [optional filespec] /MIR /MT:16

Where:

source path is the path to the directory you want to copy

dest path is the path to the destination directory

filespec specifies any file filters for files you want to copy (default is *.*)

MT is the number of threads to use (see discussion below)

When using robocopy, you should choose the “/mt” parameter to maximize throughput. This lets you control how many parallel threads do the copy, essentially controlling the queue depth of the IO requests to storage. A very low thread count does not queue enough requests on the server to let you take advantage of the inherent parallelism of our cloud architecture. A very high thread count risks server-side throttling, which end up reducing throughput. In our testing, we have found queue depths between 16 to 32 to be best for maximizing throughput.

Methods to avoid:

We have found it suboptimal to use xcopy or Windows Explorer to do large file copies to Azure Files. Those tools work great for file copies to NTFS filesystems, but do not provide sufficient parallelism for copying to Azure Files. Azure Files supports highly parallel IO, so many threads doing concurrent copies results in significantly better performance. Using robocopy with the right thread count provides much higher throughput for the copy, resulting in shorter total time to transfer the data.

3. Azure Blob to Azure File

The fastest way to move data from Azure Blobs to Azure File is to use AzCopy. You should run AzCopy from a VM in the same datacenter as the destination storage account.

An example AzCopy command for doing this is below:

AzCopy https://myaccount1.blob.core.windows.net/mycontainer Z:\mydirectory *.* /SourceKey:myStorageAccountKey

(This assumes that the File share is mapped to drive Z)

In this case the data is downloaded to the VM and then copied to Azure Files.

For details on how to use AzCopy, see discussion in section 1 above. To see the command-line options for blobs and other blob-specific options like SAS, run AzCopy with “AzCopy /?”.

4. Cloud Drive to Azure Disk

Cloud Drive was released as a preview in 2010. It enabled customers using Azure Cloud Services to mount a page blob as a drive on Web and Worker Roles in Azure. With the release of Azure Files, all the scenarios supported by Cloud Drive can now be better served using Azure Files. Cloud Drives will be deprecated in 2015, so we recommend any customers still using Cloud Drives to migrate their data to Azure Files. The way to move the data is very similar to moving data from Azure VMs using VHDs:

  1. Mount the blob as a disk using Cloud Drive (most customers do this as part of the Web or Worker roles’ setup)
  2. Mount the share on your VM. See this blog post on how to create and mount a share.
  3. Use Robocopy to copy the data. See discussion in section 3 on using Robocopy, and the “/mt” parameter for maximum throughput.

We hope these options of moving data to Azure Files will help move your data to the File Service efficiently and help you use the Service to optimize your existing scenarios while enabling new scenarios for your applications and business.

Atul Sikaria


(Cross-Post) Microsoft Azure Storage Service Version Removal

$
0
0

 

The Storage Service was initially introduced in 2008, and since then we have released seven version updates, each refining the protocol and adding new features. We are announcing the upcoming removal and removal of some earlier versions of our REST API. This post will outline all you need to know to ensure that your application continues to run well after these versions have been removed.

Background: Storage Service Versioning

What is versioning?

Azure Storage is accessed using REST API’s. These APIs were first released in 2008. As we have improved the service through additions and changes, we have used versioning to avoid breaking existing applications. Any time we make a change that could break an existing application, we introduce a new version, which applications must explicitly opt-in to use. Existing applications will be unaffected by the new version’s existence. Calls to storage generally specify the version to be used in one of the following ways:

  1. api-version query parameter: this can be specified for any call made to storage as long as sv and x-ms-version are not specified, or if specified are using version 2014 or greater. This api-version parameter will dictate the service version used.
  2. x-ms-version request header: this is required for calls made using Shared Key authentication. The x-ms-version header specifies a version, which informs the service how to interpret the request, and how to form the response for a client using that version of the REST API.
  3. SAS version header: in versions 2012 and 2013, the version specified in the “sv” parameter of a Shared Access Signature (SAS) token would specify the protocol version. In version 2014, the “sv” parameter only specifies the protocol version if the api-version query parameter is not specified.
  4. DefaultServiceVersion: The user can set this using SetServiceProperties on the Blob Service to set the version of the API which will be used for requests with no version specified (namely, requests for public blobs).
  5. Default: If a request is made for a public blob and the DefaultServiceVersion has not been set, the service default will be used. This was our initial, 2008 version, unless SetContainerACL had been set, in which case version 2009 is used (regardless of the version that was used for SetContainerACL).

The full rules used to determine the version of a request can be found on MSDN.

What about Client Libraries and tools?

Many of our users use the Storage Client Libraries provided by Microsoft for developing their applications. Each of these client libraries is essentially bound to a specific version of the REST API. This also applies to our PowerShell cmdlets and AzCopy. The Storage Emulator supports all versions of the REST API that have been released when that version of the Storage Emulator is released.

What’s changing?

Our approach to versioning is unchanged – we will continue to introduce new versions of our REST API whenever we make changes that might break an existing application. However, we will now be removing several of our earlier service versions which were released early in the lifetime of the storage service.

Removal Details

What versions are being removed?

All versions prior to version 2012-02-12 will be removed on August 1st, 2015. This includes the following versions:

The following versions are unaffected and continue to be fully supported:

When will these versions be removed?

The five affected versions will be removed on August 1st, 2015.

What will happen when these versions are removed?

The following changes will occur when removal takes effect.

Explicitly Versioned Requests

Requests which are explicitly versioned using x-ms-version request header (set to one of the removed versions) will fail, receiving an HTTP 400 (Bad Request) status code, similar to any request made with an invalid version header.

SAS Requests with no “sv” parameter

Prior to version 2012-02-12, a SAS request did not specify a version in the “sv” parameter of the SAS token. The SAS token parameters of these requests were interpreted using the rules for the 2009-07-17 REST version. When the versions prior to 2012-02-12 are removed, these requests will fail, receiving an HTTP 400 (Bad Request) status code, regardless of whether x-ms-version is specified as a supported version. For SAS requests to continue working, they must specify the “sv” parameter. Using at least version 2014-02-14 is recommended.

Default Service Version and Anonymous Requests with no explicit version

If Set Blob Service Properties (REST API) has been used to set the default version of requests to version 2012-02-12 or higher, the version set will be used. If the default version was unset, then it assumed that the request is version agnostic, and going forward we will start to respond with version 2014-02-14. Note that we make no guarantees about whether or not there will be breaking changes when unversioned requests start to get the new service version, so best practice continues to be that providing a version is always best.

If default service version was set to a version that is now removed, that request is considered to be explicitly versioned, and will fail with “400 Bad Request”. If default service version was set to a version that is still supported, that version will continue to be used.

SharedKey/SharedKeyLite Requests with no explicit version

For requests that were signed using the account’s shared key, if no explicit version is specified using x-ms-version header or api-version query parameter (supported in version 2014-02-14 and above), the requests will fail with 400 Bad Request.

Note: It is considered best practice to ensure that all requests made to the storage service are explicitly versioned. Beginning in version 2014-02-14, requests can be explicitly versioned using the api-version query string parameter, so that even clients that cannot specify custom headers can specify a version by including this parameter in their query string. See MSDN for a discussion of versioning in Azure Storage and best practices to follow.

Minimum Supported Versions/Libraries/SDK’s

Users should upgrade to the latest version whenever possible. The below table is provided to allow users to quickly see if they are using any components that target the versions to be removed.

LanguageEarliest Supported Version Using Service Version 2012-02-12 or later
.NET2.0. This was first included in Azure SDK version 2.1.
Java0.3
C++All
Windows PhoneAll
WinRTAll
AndroidAll
PHPNo released version currently supports version 2012-02-12 – an update will be coming soon.
Node.jsThe current released version supports 2012-02-12
RubyThe current released version supports 2012-02-12
PythonThe current released version supports 2012-02-12
PowerShellAll
CLIThe current released version supports 2012-02-12

 

What should I do?

To ensure that your application continues to work properly after removal, you should do the following things.

Check your application to find what versions it is using

The first thing to do is to determine what REST versions your application is using. If your application is under your control and you have confidence you are aware of all of all of the components of it which make calls to Azure Storage, then you can verify this by checking the components used against the above list, or by inspecting your code if you have written your own code to make calls to storage.

As a stronger check, or if you are unsure which versions of the components have been deployed, you can enable logging, which will log the requests being made to your storage account. The logs have the request version used included, which can be used to find if any requests are being made using versions with planned removal. Here is a sample log entry, with the version used highlighted – in this case the request was an anonymous GetBlob request which implicitly used the 2009-09-19 version:

1.0;2011-08-09T18:52:40.9241789Z;GetBlob;AnonymousSuccess;200;18;10;anonymous;;myaccount;blob;"https:// myaccount.blob.core.windows.net/thumbnails/lake.jpg?timeout=30000";"/myaccount/thumbnails/lake.jpg";a84aa705-8a85-48c5-b064-b43bd22979c3;0;123.100.2.10;2009-09-19;252;0;265;100;0;;;"0x8CE1B6EA95033D5";Friday, 09-Aug-11 18:52:40 GMT;;;;"8/9/2011 6:52:40 PM ba98eb12-700b-4d53-9230-33a3330571fc"

What to change

If you find any log entries which show that version to be removed is being used, you will need to find that component and either validate that it will continue to work (unversioned requests may continue to work as their implicit version will simply increase – see above), or take appropriate steps to change the version being used. Most commonly, one of the following two steps will be used:

1) Change the version specified in the request, typically by migrating to a later version of the libraries/tools. When possible, migrate to the latest version to get the most improvements and fixes.

2) Set the default service version to one of the supported versions now so that the behavior can be verified prior to removal. This only applies to anonymous requests with no explicit version.

When migrating your applications to newer versions, you should review the above linked change lists for each service version and test thoroughly to ensure that your application is working properly after you’ve updated it. Please note that the service version updates included both included syntactic breaks (the request will receive a response that either is a failure or formed very differently) and semantic breaks (the request will receive a similar response that means something different).

Post migration validation

After the migration, you should validate in the logs that you do not find any of the earlier versions anymore. This is the surest way to know that your application is not using any of the versions to be removed. Make sure to check the logs over long enough durations of time to be sure that there are no tasks/workloads running rarely that would still use the older versions (scheduled tasks that run once per day, for example).

Conclusion

It is recommended that users begin their application upgrades now in order to avoid being impacted when the earlier service versions are removed on August 1st, 2015.

Jeff Irwin

Introducing Zone Redundant Storage

$
0
0

We are pleased to introduce Zone Redundant Storage (ZRS) as an additional redundancy option for Azure Storage. Customers can already choose from three options today: Locally Redundant Storage (LRS), Geo Redundant Storage (GRS) and Read-Access Geo Redundant storage (RA-GRS). ZRS provides customers another choice of redundancy, durability and price-point.

The following summarizes our existing offers:

Locally Redundant Storage (LRS): LRS keeps 3 replicas of your data within a single facility within a single region for durability.

Geo Redundant Storage (GRS): This is the default option for redundancy when a storage account is created. With GRS your data is replicated across two regions, and 3 replicas of your data are kept in each of the two regions.

Read Access - Geo Redundant Storage (RA-GRS): This is the recommended option for production services relying on Azure Storage. For a GRS storage account, you have the ability to leverage higher availability by reading the storage account’s data in the secondary region.

Introducing Zone Redundant Storage (ZRS)

As you can see, these options provide a continuum of durability and availability options. ZRS fits between LRS and GRS in terms of durability and price. ZRS stores 3 replicas of your data across 2 to 3 facilities. It is designed to keep all 3 replicas within in a single region, but may span across two regions. ZRS currently only supports block blobs. ZRS allows customers to store blob at a higher durability than a single facility can provide with LRS. ZRS accounts do not have metrics or logging capability enabled at this time.

 

Creating a ZRS Account

To create a ZRS account, you will need to log in to the azure management portal. From there, you can create a new storage account, selecting ZRS as the pricing tier. Since ZRS accounts only support Block Blobs, you will not see the table, queue or file endpoints listed on the portal for the new account. Also the monitoring section will be missing since ZRS accounts do not support metrics and logging at this time.

You can also use the Service Management API to create a new ZRS storage account. You will need to use Service Management API version 2014-06-01 or above. As with the portal, the Service Management API also returns just the blob endpoint for the newly created account, since tables, queues and files are not supported for ZRS accounts. Also, if you use Service Management API versions prior to 2014-06-01 to enumerate storage accounts, then any ZRS accounts will not be included in the enumeration. Similarly, attempting to retrieve properties of a storage account using API before 2014-06-01 will result in the request to fail.

You will need to be careful in your selection of redundancy level, since a ZRS account cannot be converted later to LRS or GRS. Similarly, an existing LRS or GRS account cannot be converted to a ZRS account. If you have existing blobs in blob storage and you want to use ZRS, then you have to create a ZRS account, and copy the blobs to the new account using AzCopy or the REST API.

Using a ZRS account

ZRS accounts can be accessed using the Azure Storage REST API, or our numerous client SDKs in various languages and platforms. Storage REST API version 2014-02-14 is the minimum REST version supported by ZRS accounts. Our client SDKs have been updated to support ZRS. The .net client supports ZRS as of version 4.0.0 and above, and the java client supports ZRS as of version 1.0.0. If you are using an older version of the SDK, you will need to upgrade to use a ZRS account.

Since ZRS accounts do not support page blob, file, table or queue, any attempt to create or manipulate those objects on a ZRS storage account will fail.

For accessing block blobs, there are no changes required to your code – just use the block blob APIs as you are used to today.

Pricing

The most up-to-date pricing for ZRS can be found on our pricing page.

As always, we are looking forward to your feedback.

Microsoft Azure Storage Team

AzCopy 2.5 Release

$
0
0

We are pleased to announce the release of AzCopy version 2.5 which can be found here. This version includes several important improvements for performance and usability. We have also created a comprehensive Getting Started tutorial for AzCopy which helps summarizes the syntax for AzCopy as well as guidance for key scenarios. This tutorial can be found here.

AzCopy 2.5 offers these enhancements:

  • AzCopy now supports the transfer of an unlimited number of blobs/files. The upper limit on blob/file transfers has been eliminated by keeping the memory usage of AzCopy constant, despite the fact that the number of files being transferred may vary.
  • AzCopy now permits the user to supply a SAS token for the destination blob, if the data is being copied within same storage account.
  • Previously, it was necessary to specify the command-line option /z to generate a journal file. AzCopy v2.5 will now always generate a journal file, even if the user does not specify option /z.
    By default, the journal files are written to the folder
    %localAppData%\Microsoft\Azure\AzCopy\. You can use the /z:[journal file folder] option to override the default journal folder. For more details about option /z, type AzCopy /? in the command line window.
  • The default folder for the AzCopy verbose log is now
    %localAppData%\Microsoft\Azure\AzCopy\.
  • Due to performance considerations, AzCopy no longer supports multiple file patterns in a single command. Users must now issue multiple commands with one file pattern each to address the scenario of multiple file patterns.
  • AzCopy now allows users to specify the installation path in the installation wizard.
  • AzCopy version 2.5 expands the scope of option /Y, such that this option not only suppresses confirmation prompts when overwriting the destination blobs/files, but also suppresses all other confirmation prompts.
  • AzCopy will now alert the user when it is attempting to resolve naming differences between the Blob service and the Windows file system. Some key differences between naming rules for the Blob service and Windows File include:
    1. The upper limit for the length of a blob name is 1024 characters, as compared to the 260 characters (file absolutely path length) which is often required for backward compatibility with older Windows applications.
    2. The Blob service allows for a blank blob name, while the Windows file system does not
    3. Some file names are reserved by the Windows file system, but are permitted for blob names.
    4. The Blob service supports case-sensitive blob names, while Windows file system does not.
    When AzCopy detects naming conflicts when downloading blobs to the Windows file system, it will report the error to the end user.
    We recommend that the user name files so as to meet the constraints of both naming schemes, in order to avoid transfer failures.
  • The command-line option /mov has been removed, as in a limited number of circumstances multiple source files with the same file name could overwrite a single destination file – for example – copying files from storage which uses case sensitive file names to the Windows file system which is case insensitive.

Note that you can always type AzCopy /? for additional details about command-line options and usage.

Windows Azure Storage Team

(Cross-Post) Managing Concurrency in Microsoft Azure Storage

$
0
0

Modern Internet based applications usually have multiple users viewing and updating data simultaneously. This requires application developers to think carefully about how to provide a predictable experience to their end users, particularly for scenarios where multiple users can update the same data. There are three main data concurrency strategies developers will typically consider:

  1. Optimistic concurrency – An application performing an update will as part of its update verify if the data has changed since the application last read that data. For example, if two users viewing a wiki page make an update to the same page then the wiki platform must ensure that the second update does not overwrite the first update – and that both users understand whether their update was successful or not. This strategy is most often used in web applications.
  2. Pessimistic concurrency – An application looking to perform an update will take a lock on an object preventing other users from updating the data until the lock is released. For example, in a master/slave data replication scenario where only the master will perform updates the master will typically hold an exclusive lock for an extended period of time on the data to ensure no one else can update it.
  3. Last writer wins – An approach that allows any update operations to proceed without verifying if any other application has updated the data since the application first read the data. This strategy (or lack of a formal strategy) is usually used where data is partitioned in such a way that there is no likelihood that multiple users will access the same data. It can also be useful where short-lived data streams are being processed.

This blog post provides an overview of how the Azure Storage platform simplifies development by providing first class support for all three of these concurrency strategies.

Azure Storage – Simplifies Cloud Development

The Azure storage service supports all three strategies, although it is distinctive in its ability to provide full support for optimistic and pessimistic concurrency because it was designed to embrace a strong consistency model which guarantees that when the Storage service commits a data insert or update operation all further accesses to that data will see the latest update. Storage platforms that use an eventual consistency model have a lag between when a write is performed by one user and when the updated data can be seen by other users thus complicating development of client applications in order to prevent inconsistencies from affecting end users.

In addition to selecting an appropriate concurrency strategy developers should also be aware of how a storage platform isolates changes – particularly changes to the same object across transactions. The Azure storage service uses snapshot isolation to allow read operations to happen concurrently with write operations within a single partition. Unlike other isolation levels, snapshot isolation guarantees that all reads see a consistent snapshot of the data even while updates are occurring – essentially by returning the last committed values while an update transaction is being processed.

Managing Concurrency in the Blob Service

You can opt to use either optimistic or pessimistic concurrency models to manage access to blobs and containers in the blob service. If you do not explicitly specify a strategy last writes wins is the default.

Optimistic concurrency for blobs and containers

The Storage service assigns an identifier to every object stored. This identifier is updated every time an update operation is performed on an object. The identifier is returned to the client as part of an HTTP GET response using the ETag (entity tag) header that is defined within the HTTP protocol. A user performing an update on such an object can send in the original ETag along with a conditional header to ensure that an update will only occur if a certain condition has been met – in this case the condition is an “If-Match” header which requires the Storage Service to ensure the value of the ETag specified in the update request is the same as that stored in the Storage Service.

The outline of this process is as follows:

  1. Retrieve a blob from the storage service, the response includes an HTTP ETag Header value that identifies the current version of the object in the storage service.
  2. When you update the blob, include the ETag value you received in step 1 in the If-Match conditional header of the request you send to the service.
  3. The service compares the ETag value in the request with the current ETag value of the blob.
  4. If the current ETag value of the blob is a different version than the ETag in the If-Match conditional header in the request, the service returns a 412 error to the client. This indicates to the client that another process has updated the blob since the client retrieved it.
  5. If the current ETag value of the blob is the same version as the ETag in the If-Match conditional header in the request, the service performs the requested operation and updates the current ETag value of the blob to show that it has created a new version.

The following C# snippet (using the Client Storage Library 4.2.0) shows a simple example of how to construct an If-MatchAccessCondition based on the ETag value that is accessed from the properties of a blob that was previously either retrieved or inserted. It then uses the AccessCondition object when it updating the blob: the AccessCondition object adds the If-Match header to the request. If another process has updated the blob, the blob service returns an HTTP 412 (Precondition Failed) status message. The full sample can be downloaded here.

// Retrieve the ETag from the newly created blob
// Etag is already populated as UploadText should cause a PUT Blob call 
// to storage blob service which returns the etag in response.
string orignalETag = blockBlob.Properties.ETag;
 
// This code simulates an update by a third party.
string helloText = "Blob updated by a third party.";
 
// No etag, provided so orignal blob is overwritten (thus generating a new etag)
blockBlob.UploadText(helloText);
Console.WriteLine("Blob updated. Updated ETag = {0}", 
blockBlob.Properties.ETag);
 
// Now try to update the blob using the orignal ETag provided when the blob was created
try
{
    Console.WriteLine("Trying to update blob using orignal etag to generate if-match access condition");
    blockBlob.UploadText(helloText,accessCondition:
    AccessCondition.GenerateIfMatchCondition(orignalETag));
}
catch (StorageException ex)
{
if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
    {
        Console.WriteLine("Precondition failure as expected. Blob's orignal etag no longer matches");
// TODO: client can decide on how it wants to handle the 3rd party updated content.
    }
else
throw;
}

The Storage Service also includes support for additional conditional headers such as If-Modified-Since, If-Unmodified-Since and If-None-Match as well as combinations thereof.For more information see Specifying Conditional Headers for Blob Service Operations on MSDN.

The following table summarizes the container operations that accept conditional headers such as If-Match in the request and that return an ETag value in the response.

Operation

Returns Container ETag value

Accepts conditional headers

Create Container

Yes

No

Get Container Properties

Yes

No

Get Container Metadata

Yes

No

Set Container Metadata

Yes

Yes

Get Container ACL

Yes

No

Set Container ACL

Yes

Yes (*)

Delete Container

No

Yes

Lease Container

Yes

Yes

List Blobs

No

No

(*) The permissions defined by SetContainerACL are cached and updates to these permissions take 30 seconds to propagate during which period updates are not guaranteed to be consistent.

The following table summarizes the blob operations that accept conditional headers such as If-Match in the request and that return an ETag value in the response.

Operation

Returns ETag value

Accepts conditional headers

Put Blob

Yes

Yes

Get Blob

Yes

Yes

Get Blob Properties

Yes

Yes

Set Blob Properties

Yes

Yes

Get Blob Metadata

Yes

Yes

Set Blob Metadata

Yes

Yes

Lease Blob (*)

Yes

Yes

Snapshot Blob

Yes

Yes

Copy Blob

Yes

Yes (for source and destination blob)

Abort Copy Blob

No

No

Delete Blob

No

Yes

Put Block

No

No

Put Block List

Yes

Yes

Get Block List

Yes

No

Put Page

Yes

Yes

Get Page Ranges

Yes

Yes

(*) Lease Blob does not change the ETag on a blob.

Pessimistic concurrency for blobs

To lock a blob for exclusive use, you can acquire a lease on it. When you acquire a lease, you specify for how long you need the lease: this can be for between 15 to 60 seconds or infinite which amounts to an exclusive lock. You can renew a finite lease to extend it, and you can release any lease when you are finished with it. The blob service automatically releases finite leases when they expire.

Leases enable different synchronization strategies to be supported, including exclusive write / shared read, exclusive write / exclusive read and shared write / exclusive read. Where a lease exists the storage service enforces exclusive writes (put, set and delete operations) however ensuring exclusivity for read operations requires the developer to ensure that all client applications use a lease ID and that only one client at a time has a valid lease ID. Read operations that do not include a lease ID result in shared reads.

The following C# snippet shows an example of acquiring an exclusive lease for 30 seconds on a blob, updating the content of the blob, and then releasing the lease. If there is already a valid lease on the blob when you try to acquire a new lease, the blob service returns an “HTTP (409) Conflict” status result. The snippet below uses an AccessCondition object to encapsulate the lease information when it makes a request to update the blob in the storage service. The full sample can be downloaded here.

// Acquire lease for 15 seconds
string lease = blockBlob.AcquireLease(TimeSpan.FromSeconds(15), null);
Console.WriteLine("Blob lease acquired. Lease = {0}", lease);
 
// Update blob using lease. This operation will succeed
conststring helloText = "Blob updated";
var accessCondition = AccessCondition.GenerateLeaseCondition(lease);
blockBlob.UploadText(helloText, accessCondition: accessCondition);
Console.WriteLine("Blob updated using an exclusive lease");
 
//Simulate third party update to blob without lease
try
{
// Below operation will fail as no valid lease provided
    Console.WriteLine("Trying to update blob without valid lease");
    blockBlob.UploadText("Update without lease, will fail");
}
catch (StorageException ex)
{
if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
        Console.WriteLine("Precondition failure as expected. Blob's lease does not match");
else
throw;
}

If you attempt a write operation on a leased blob without passing the lease id, the request fails with a 412 error. Note that if the lease expires before calling the UploadText method but you still pass the lease id, the request also fails with a 412 error. For more information about managing lease expiry times and lease ids, see the Lease Blob REST documentation.

The following blob operations can use leases to manage pessimistic concurrency:

  • Put Blob
  • Get Blob
  • Get Blob Properties
  • Set Blob Properties
  • Get Blob Metadata
  • Set Blob Metadata
  • Delete Blob
  • Put Block
  • Put Block List
  • Get Block List
  • Put Page
  • Get Page Ranges
  • Snapshot Blob - lease id optional if a lease exists
  • Copy Blob - lease id required if a lease exists on the destination blob
  • Abort Copy Blob - lease id required if an infinite lease exists on the destination blob
  • Lease Blob

Pessimistic concurrency for containers

Leases on containers enable the same synchronization strategies to be supported as on blobs (exclusive write / shared read, exclusive write / exclusive read and shared write / exclusive read) however unlike blobs the storage service only enforces exclusivity on delete operations. To delete a container with an active lease, a client must include the active lease ID with the delete request. All other container operations succeed on a leased container without including the lease ID in which case they are shared operations. If exclusivity of update (put or set) or read operations is required then developers should ensure all clients use a lease ID and that only one client at a time has a valid lease ID.

The following container operations can use leases to manage pessimistic concurrency:

  • Delete Container
  • Get Container Properties
  • Get Container Metadata
  • Set Container Metadata
  • Get Container ACL
  • Set Container ACL
  • Lease Container

For more information see:

- Specifying Conditional Headers for Blob Service Operations

- Lease Container

- Lease Blob

Managing Concurrency in the Table Service

The table service uses optimistic concurrency checks as the default behavior when you are working with entities, unlike the blob service where you must explicitly choose to perform optimistic concurrency checks. The other difference between the table and blob services is that you can only manage the concurrency behavior of entities whereas with the blob service you can manage the concurrency of both containers and blobs.

To use optimistic concurrency and to check if another process modified an entity since you retrieved it from the table storage service, you can use the ETag value you receive when the table service returns an entity. The outline of this process is as follows:

  1. Retrieve an entity from the table storage service, the response includes an ETag value that identifies the current identifier associated with that entity in the storage service.
  2. When you update the entity, include the ETag value you received in step 1 in the mandatory If-Match header of the request you send to the service.
  3. The service compares the ETag value in the request with the current ETag value of the entity.
  4. If the current ETag value of the entity is different than the ETag in the mandatory If-Match header in the request, the service returns a 412 error to the client. This indicates to the client that another process has updated the entity since the client retrieved it.
  5. If the current ETag value of the entity is the same as the ETag in the mandatory If-Match header in the request or the If-Match header contains the wildcard character (*), the service performs the requested operation and updates the current ETag value of the entity to show that it has been updated.

Note that unlike the blob service, the table service requires the client to include an If-Match header in update requests. However, it is possible to force an unconditional update (last writer wins strategy) and bypass concurrency checks if the client sets the If-Match header to the wildcard character (*) in the request.

The following C# snippet shows a customer entity that was previously either created or retrieved having their email address updated. The initial insert or retrieve operation stores the ETag value in the customer object, and because the sample uses the same object instance when it executes the replace operation, it automatically sends the ETag value back to the table service, enabling the service to check for concurrency violations. If another process has updated the entity in table storage, the service returns an HTTP 412 (Precondition Failed) status message. The full sample can be downloaded here.

try
{
    customer.Email = "updatedEmail@contoso.org";
    TableOperation replaceCustomer = TableOperation.Replace(customer);
    customerTable.Execute(replaceCustomer);
    Console.WriteLine("Replace operation succeeded.");
}
catch (StorageException ex)
{
if (ex.RequestInformation.HttpStatusCode == 412)
        Console.WriteLine("Optimistic concurrency violation – entity has changed since it was retrieved.");
else
throw; 
}

To explicitly disable the concurrency check, you should set the ETag property of the employee object to “*” before you execute the replace operation.

customer.ETag = "*";

The following table summarizes how the table entity operations use ETag values:

Operation

Returns ETag value

Requires If-Match request header

Query Entities

Yes

No

Insert Entity

Yes

No

Update Entity

Yes

Yes

Merge Entity

Yes

Yes

Delete Entity

No

Yes

Insert or Replace Entity

Yes

No

Insert or Merge Entity

Yes

No

Note that the Insert or Replace Entity and Insert or Merge Entity operations do not perform any concurrency checks because they do not send an ETag value to the table service.

In general developers using tables should rely on optimistic concurrency when developing scalable applications. If pessimistic locking is needed, one approach developers can take when accessing Tables is to assign a designated blob for each table and try to take a lease on the blob before operating on the table. This approach does require the application to ensure all data access paths obtain the lease prior to operating on the table. You should also note that the minimum lease time is 15 seconds which requires careful consideration for scalability.

For more information see:

- Operations on Entities

Managing Concurrency in the Queue Service

One scenario in which concurrency is a concern in the queueing service is where multiple clients are retrieving messages from a queue. When a message is retrieved from the queue, the response includes the message and a pop receipt value, which is required to delete the message. The message is not automatically deleted from the queue, but after it has been retrieved, it is not visible to other clients for the time interval specified by the visibilitytimeout parameter. The client that retrieves the message is expected to delete the message after it has been processed, and before the time specified by the TimeNextVisible element of the response, which is calculated based on the value of the visibilitytimeout parameter. The value of visibilitytimeout is added to the time at which the message is retrieved to determine the value of TimeNextVisible.

The queue service does not have support for either optimistic or pessimistic concurrency and for this reason clients processing messages retrieved from a queue should ensure messages are processed in an idempotent manner. A last writer wins strategy is used for update operations such as SetQueueServiceProperties, SetQueueMetaData, SetQueueACL and UpdateMessage.

For more information see:

- Queue Service REST API

- Get Messages

Managing Concurrency in the File Service

The file service can be accessed using two different protocol endpoints – SMB and REST. The REST service does not have support for either optimistic locking or pessimistic locking and all updates will follow a last writer wins strategy. SMB clients that mount file shares can leverage file system locking mechanisms to manage access to shared files – including the ability to perform pessimistic locking. When an SMB client opens a file, it specifies both the file access and share mode. Setting a File Access option of "Write" or "Read/Write" along with a File Share mode of "None" will result in the file being locked by an SMB client until the file is closed. If REST operation is attempted on a file where an SMB client has the file locked the REST service will return status code 409 (Conflict) with error code SharingViolation.

When an SMB client opens a file for delete, it marks the file as pending delete until all other SMB client open handles on that file are closed. While a file is marked as pending delete, any REST operation on that file will return status code 409 (Conflict) with error code SMBDeletePending. Status code 404 (Not Found) is not returned since it is possible for the SMB client to remove the pending deletion flag prior to closing the file. In other words, status code 404 (Not Found) is only expected when the file has been removed. Note that while a file is in a SMB pending delete state, it will not be included in the List Files results.Also note that the REST Delete File and REST Delete Directory operations are committed atomically and do not result in pending delete state.

For more information see:

- Managing File Locks

Summary and Next Steps

The Microsoft Azure Storage service has been designed to meet the needs of the most complex online applications without forcing developers to compromise or rethink key design assumptions such as concurrency and data consistency that they have come to take for granted.

For the complete sample application referenced in this blog:

- Managing Concurrency using Azure Storage - Sample Application

For more information on Azure Storage see:

- Microsoft Azure Storage Home Page

- Introduction to Azure Storage

- Storage Getting Started for Blob, Table and Queues

- Storage Architecture – Windows Azure Storage : A Highly Available Cloud Storage Service with Strong Consistency

Jason Hogg

(Cross-Post) Monitoring, Diagnosing and Troubleshooting Azure Storage

$
0
0

Diagnosing and troubleshooting issues in modern online applications is more complex than in traditional client-server applications because they include:

  • Complex topologies with components running PaaS or IaaS infrastructure, on-premises, on mobile devices, or some combination of these
  • Network traffic that traverses public and private networks; including devices with unpredictable connectivity
  • Multiple storage technologies such as Microsoft Azure Storage Tables, Blobs, Queues, or Files in addition to other data stores such as relational databases.

The Azure Storage service includes sophisticated capabilities to help you to manage these challenges. These capabilities include enabling you to monitor the Storage services your application uses for any unexpected changes in behavior (such as slower than usual response times) as well as extensive logging capabilities – both in the storage service and client applications developed with the storage client libraries. The information you obtain from both monitoring and logging will help you to diagnose and troubleshoot the issue and determine the appropriate steps you can take to remediate it. The analytics capability has been designed not to affect the performance of your operations, plus includes the ability to define retention policies for managing the amount of storage consumed.

To help you learn how to manage the health of your online services we have developed the Storage Monitoring, Diagnosing and Troubleshooting Guide. This includes prescriptive guidance on monitoring and diagnosing problems related to health, availability, performance and capacity – as well as actionable troubleshooting guidance for the top issues that ourselves and our support teams face when working with customers. For anyone building Storage based applications we believe this guide is essential reading! The illustration below shows extracts from each of the sections focused on how to manage the performance of your application.

clip_image002

Example Scenario – Investigating the performance degradation of an application

To illustrate how the guide can help you, we will walk through a scenario that we see frequently – and that is where a customer reports that the performance of their application is slower than normal. If the customer doesn’t have a monitoring strategy in place it can be difficult and time consuming to determine the root cause of this problem.

The monitoring section of the guide walks you through some key metrics that you should be capturing and monitoring on an ongoing basis looking for unexpected changes in these values as an indicator that you may have an issue that needs investigation. Two metrics that are relevant to this particular scenario are the AverageE2ELatency and AverageServerLatency metrics. AverageE2ELatency is a measure of end-to-end latency that includes the time taken by our service to read the request from the client and send the response back to the client in addition to the time taken to process the request (therefore includes network latency once the request reaches the storage service); AverageServerLatency is a measure of just the processing time by our service and therefore excludes any network latency related to communicating with the client or latencies associated with the client application populating and consuming the send and response buffers.

image

From looking at the metrics data in the portal (see the illustration above) the AverageE2Elatency is significantly higher than the AverageServerLatency. The first thing you would now want to do is compare this with baseline metrics that you should establish through ongoing monitoring of your service – and initially during performance testing of your application and a limited release to production. For now we will assume this discrepancy is indeed an issue outside of the Azure Storage Service – at which point we can use the troubleshooting decision tree to take you to the section "Metrics show high AverageE2ELatency and low AverageServerLatency". This section then discusses different possibilities to explore:

  • Client performance issues - Possible reasons for the client responding slowly include having a limited number of available connections or threads, or being low on resources such as CPU, memory or network bandwidth. You may be able to resolve the issue by modifying the client code to be more efficient (for example by using asynchronous calls to the storage service), or by using a larger Virtual Machine (with more cores and more memory)… See here for more information.
  • Network latency issues - Typically, high end-to-end latency caused by the network is due to transient conditions. You can investigate both transient and persistent network issues such as dropped packets by using tools such as Wireshark or Microsoft Message Analyzer. For more information about using Wireshark to troubleshoot network issues, see "Appendix 2: Using Wireshark to capture network traffic." For more information about using Microsoft Message Analyzer to troubleshoot network issues, see "Appendix 3: Using Microsoft Message Analyzer to capture network traffic."… See here for more information.

After reading the client performance section and verifying that the discrepancy between AverageE2ELatency and AverageServerLatency was only occurring for queue operations and not for blob operations the guide directs you to read an article about the Nagle algorithm and how it is not friendly towards small requests. After appropriate testing this was identified as being the problem and the code was updated to turn off Nagle’s algorithm. Doing so and monitoring our AverageE2ELatency after the change showed a marked improvement in AverageE2ELatency.

Other issues that can cause intermittent fluctuations in response times include poor network conditions and server side failures. In either of these situations the client application may retry an operation thus increasing the perceived latency for that particular operation. In these cases you would likely see both AverageE2ELatency and AverageServerLatency being low. In this situation the troubleshooting decision tree would take you to this section “Metrics show low AverageE2ELatency and low AverageServerLatency but the client is experiencing high latency" which walks you through appropriate troubleshooting techniques. The section on "End-to-end tracing” also provides additional information on how client and server request correlation can assist in troubleshooting these types of issues.

Hopefully this scenario demonstrates the importance of proactively monitoring your service plus having a good understanding of the different tools available to assist you when problems do occur.

Summary and Call to Action

To help you learn how to manage the health of your online services we have developed the Storage Monitoring, Diagnosing and Troubleshooting Guide. This includes prescriptive guidance on monitoring and diagnosing problems related to health, capacity, availability and performance – as well as actionable suggestions for troubleshooting top issues that ourselves and our support teams face in working with customers.

We have also looked at related guidance and created / updated content relating to:

In terms of next steps we recommend:

  • Enable metrics and logging on your production storage accounts – as it is not enabled by default
  • Read the monitoring and diagnosing sections of the guide so you can update your management policies
  • Book mark the guide to assist with troubleshooting when problems do occur

We hope this guidance makes managing your online services much simpler!

Jason Hogg

Viewing all 167 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>