Created
August 10, 2011 16:28
-
-
Save tomconte/1137333 to your computer and use it in GitHub Desktop.
Sample command-line utility to enable Storage Analytics on Windows Azure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Net; | |
using Microsoft.WindowsAzure; | |
using System.IO; | |
using System.Xml.Linq; | |
using NDesk.Options; | |
namespace StorageAnalytics | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string account = null, accessKey = null, type = null; | |
bool getOperation = false, listOperation = false; | |
string filePath = null; | |
StorageCredentialsAccountAndKey creds; | |
// Define command-line arguments | |
var p = new OptionSet() | |
{ | |
{ "a|account=", "{account} name", v => account = v }, | |
{ "k|key=", "access {key}", v => accessKey = v}, | |
{ "t|type=", "storage {type}: 'blob' or 'table'", v => type = v}, | |
{ "g|get", "get current configuration", v => getOperation = true }, | |
{ "s|set=", "set current configuration from {file}", v => filePath = v }, | |
{ "l|list", "list contents of $logs container", v => listOperation = true } | |
}; | |
// Parse arguments | |
try | |
{ | |
p.Parse(args); | |
} | |
catch (OptionException e) | |
{ | |
Usage(p, e.Message); | |
return; | |
} | |
// Check the arguments | |
if (account == null || accessKey == null || type == null || (type != "blob" && type != "table")) | |
{ | |
Usage(p, "account, accesskey and type are mandatory; type must be 'blob' or 'table'"); | |
return; | |
} | |
// Create storage credentials | |
try | |
{ | |
creds = new StorageCredentialsAccountAndKey(account, accessKey); | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine("failed to create storage credentials: " + e.Message); | |
Console.WriteLine("please check account and accesskey!"); | |
return; | |
} | |
// Execute the operation | |
if (getOperation) | |
{ | |
DoGet(account, type, "?restype=service&comp=properties", creds); | |
return; | |
} | |
else if (listOperation) | |
{ | |
DoGet(account, type, "$logs/?restype=container&comp=list", creds); | |
return; | |
} | |
else if (!String.IsNullOrEmpty(filePath)) | |
{ | |
DoPut(account, type, "?restype=service&comp=properties", creds, filePath); | |
return; | |
} | |
else | |
{ | |
Usage(p, "please specify either -get or -set operation"); | |
} | |
} | |
// Send a GET REST API request & print the response body | |
private static void DoGet(string account, string type, string query, StorageCredentials creds) | |
{ | |
HttpWebRequest req; | |
HttpWebResponse resp; | |
req = CreateRequest(account, type, query, "GET", creds, null); | |
try | |
{ | |
resp = (HttpWebResponse)req.GetResponse(); | |
} | |
catch (WebException e) | |
{ | |
Console.WriteLine(e.Message); | |
return; | |
} | |
Console.WriteLine(XDocument.Parse( | |
new StreamReader( | |
resp.GetResponseStream() | |
).ReadToEnd() | |
).ToString() | |
); | |
} | |
// Send a PUT REST API request & print the HTTP response status | |
private static void DoPut(string account, string type, string query, StorageCredentials creds, string filePath) | |
{ | |
HttpWebRequest req; | |
HttpWebResponse resp; | |
req = CreateRequest(account, type, "?restype=service&comp=properties", "PUT", creds, filePath); | |
try | |
{ | |
resp = (HttpWebResponse)req.GetResponse(); | |
} | |
catch (WebException e) | |
{ | |
Console.WriteLine(e.Message); | |
return; | |
} | |
Console.WriteLine("Response: " + resp.StatusCode); | |
} | |
// Create the REST API request | |
private static HttpWebRequest CreateRequest(string account, string type, string query, string method, StorageCredentials creds, string configFile) | |
{ | |
// The URI includes the account name & service type ("blob" or "table") | |
Uri uri = new Uri(String.Format("http://{0}.{1}.core.windows.net/" + query, account, type)); | |
var timeout = new TimeSpan(0, 0, 30); | |
StreamReader fileStream = null; | |
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri); | |
req.Timeout = (int)timeout.TotalMilliseconds; | |
req.ReadWriteTimeout = (int)timeout.TotalMilliseconds; | |
req.Method = method; | |
req.Headers["x-ms-version"] = "2009-09-19"; | |
// Add the Content-Length | |
if (!String.IsNullOrEmpty(configFile)) | |
{ | |
fileStream = new StreamReader(configFile); | |
req.ContentLength = fileStream.BaseStream.Length; | |
} | |
// Each storage type requires a different signing scheme | |
if (type == "blob") | |
creds.SignRequest(req); | |
else | |
creds.SignRequestLite(req); | |
// Add the contents of the config file as the request body | |
// Must be done AFTER signing the request | |
if (fileStream != null) | |
{ | |
fileStream.BaseStream.CopyTo(req.GetRequestStream()); | |
fileStream.Close(); | |
} | |
return req; | |
} | |
// Print command-line options | |
private static void Usage(OptionSet p, string s) | |
{ | |
Console.Write("StorageAnalytics: "); | |
Console.WriteLine(s); | |
p.WriteOptionDescriptions(Console.Out); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment