Skip to content

Commit

Permalink
Merge pull request #6 from richorama/master
Browse files Browse the repository at this point in the history
More table storage stuff
  • Loading branch information
AndyCross committed Nov 13, 2013
2 parents 326c48e + b1402d4 commit c822d42
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 45 deletions.
11 changes: 2 additions & 9 deletions netmfazurestorage/Http/AzureStorageHttpHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,7 @@ public static BasicHttpResponse SendWebRequest(string url, string authHeader, st
using (var responseStream = response.GetResponseStream())
using (var reader = new StreamReader(responseStream))
{
char[] bytes = new char[(int)responseStream.Length];

if (bytes.Length > 0)
{
reader.Read(bytes, 0, bytes.Length);

responseBody = new string(bytes);
}
responseBody = reader.ReadToEnd();
}
}
}
Expand Down Expand Up @@ -89,7 +82,7 @@ public static BasicHttpResponse SendWebRequest(string url, string authHeader, st
/// <param name="contentLength"></param>
/// <param name="httpVerb"></param>
/// <returns></returns>
private static HttpWebRequest PrepareRequest(string url, string authHeader, string dateHeader, string versionHeader, byte[] fileBytes = null, int contentLength = 0, string httpVerb = "GET", bool expect100Continue = false, Hashtable additionalHeaders = null)
private static HttpWebRequest PrepareRequest(string url, string authHeader, string dateHeader, string versionHeader, byte[] fileBytes , int contentLength, string httpVerb, bool expect100Continue = false, Hashtable additionalHeaders = null)
{
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
Expand Down
7 changes: 1 addition & 6 deletions netmfazurestorage/Queue/QueueClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,12 @@
using Microsoft.SPOT;
using NetMf.CommonExtensions;
using netmfazurestorage.Http;
using System.Collections;

namespace netmfazurestorage.Queue
{
public class QueueClient
{
#region private members

private string _httpVerb = "PUT";

#endregion

#region constants

internal const string HttpVerbPut = "PUT";
Expand Down
9 changes: 9 additions & 0 deletions netmfazurestorage/StringUtilities/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ public static string Replace(this string content, string find, string replace)

}

public static bool IsNullOrEmpty(this string value)
{
return (value == null || value == "");
}

public static string Format(this string value, params string[] args)
{
return StringUtility.Format(value, args);
}

}
}
90 changes: 60 additions & 30 deletions netmfazurestorage/Table/TableClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,16 @@ public class TableClient
public static string AccountKey;
public static bool AttachFiddler;

#region constants


internal const string VersionHeader = "2011-08-18";
internal const string ContentType = "application/atom+xml";
private string DateHeader { get; set; }

#endregion

#region Properties
private Hashtable additionalHeaders;

internal DateTime InstanceDate { get; set; }

#endregion


protected byte[] GetBodyBytesAndLength(string body, out int contentLength)
{
var content = Encoding.UTF8.GetBytes(body);
Expand All @@ -44,6 +40,10 @@ public TableClient(string accountName, string accountKey)
AccountName = accountName;
AccountKey = accountKey;
DateHeader = DateTime.UtcNow.ToString("R");
additionalHeaders = new Hashtable();
additionalHeaders.Add("DataServiceVersion", "1.0;NetFx");
additionalHeaders.Add("MaxDataServiceVersion", "1.0;NetFx");
additionalHeaders.Add("Content-Type", ContentType);
}

public void CreateTable(string tableName)
Expand All @@ -62,8 +62,8 @@ public void CreateTable(string tableName)

int contentLength = 0;
byte[] payload = GetBodyBytesAndLength(xml, out contentLength);
string header = CreateAuthorizationHeader(payload, ContentType, "/" + AccountName + "/Tables()");
AzureStorageHttpHelper.SendWebRequest("http://" + AccountName + ".table.core.windows.net/Tables()", header, DateHeader, VersionHeader, payload, contentLength);
string header = CreateAuthorizationHeader(payload, "/" + AccountName + "/Tables()");
AzureStorageHttpHelper.SendWebRequest("http://" + AccountName + ".table.core.windows.net/Tables()", header, DateHeader, VersionHeader, payload, contentLength, "POST", false, this.additionalHeaders);
}

[Obsolete("Please use the InsertTableEntity method; this AddTableEntityForTemperature method will be removed in a future release.", false)]
Expand All @@ -87,8 +87,8 @@ public void AddTableEntityForTemperature(string tablename, string partitionKey,

int contentLength = 0;
byte[] payload = GetBodyBytesAndLength(xml, out contentLength);
string header = CreateAuthorizationHeader(payload, ContentType, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength);
string header = CreateAuthorizationHeader(payload, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength, "GET", false, this.additionalHeaders);
}

public void InsertTableEntity(string tablename, string partitionKey, string rowKey, DateTime timeStamp, System.Collections.ArrayList tableEntityProperties)
Expand All @@ -110,8 +110,8 @@ public void InsertTableEntity(string tablename, string partitionKey, string rowK

int contentLength = 0;
byte[] payload = GetBodyBytesAndLength(xml, out contentLength);
string header = CreateAuthorizationHeader(payload, ContentType, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength);
string header = CreateAuthorizationHeader(payload, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength, "POST", false, this.additionalHeaders);
}

public void InsertTableEntity_Experimental(string tablename, string partitionKey, string rowKey, DateTime timeStamp, Hashtable tableEntityProperties)
Expand All @@ -133,8 +133,8 @@ public void InsertTableEntity_Experimental(string tablename, string partitionKey

int contentLength = 0;
byte[] payload = GetBodyBytesAndLength(xml, out contentLength);
string header = CreateAuthorizationHeader(payload, ContentType, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength);
string header = CreateAuthorizationHeader(payload, StringUtility.Format("/{0}/{1}", AccountName, tablename));
AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}", AccountName, tablename), header, DateHeader, VersionHeader, payload, contentLength, "POST", false, this.additionalHeaders);
}

private string GetTableXml(ArrayList tableEntityProperties)
Expand Down Expand Up @@ -177,55 +177,82 @@ private static string GetTableXml(Hashtable tableEntityProperties)

public Hashtable QueryTable(string tablename, string partitionKey, string rowKey)
{
var header = CreateAuthorizationHeader(null, ContentType, StringUtility.Format("/{0}/{1}(PartitionKey='{2}',RowKey='{3}')", AccountName, tablename, partitionKey, rowKey));
var xml = AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}(PartitionKey='{2}',RowKey='{3}')", AccountName, tablename, partitionKey, rowKey), header, DateHeader, VersionHeader, null, 0, "GET");
string token = null;
Hashtable results = null;
var header = CreateAuthorizationHeader(null, StringUtility.Format("/{0}/{1}(PartitionKey='{2}',RowKey='{3}')", AccountName, tablename, partitionKey, rowKey));
var response = AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}(PartitionKey='{2}',RowKey='{3}')", AccountName, tablename, partitionKey, rowKey), header, DateHeader, VersionHeader, null, 0, "GET", false, this.additionalHeaders);
var entities = ParseResponse(response.Body);
if (entities.Count == 1)
{
return entities[0] as Hashtable;
}
return null;
}

public ArrayList QueryTable(string tablename, string query)
{
if (query.IsNullOrEmpty())
{
query = "";
}
else
{
query = "$filter=" + query.Replace(" ", "%20");
}
var header = CreateAuthorizationHeader(null, StringUtility.Format("/{0}/{1}()", AccountName, tablename));
var response = AzureStorageHttpHelper.SendWebRequest(StringUtility.Format("http://{0}.table.core.windows.net/{1}()?{2}", AccountName, tablename, query), header, DateHeader, VersionHeader, null, 0, "GET", false, this.additionalHeaders);
return ParseResponse(response.Body);
}

private ArrayList ParseResponse(string xml)
{
var results = new ArrayList();
string entityToken = null;
var nextStart = 0;
while (null != (token = NextToken(xml.Body, "<m:properties>", "</m:properties>", nextStart, out nextStart)))
while (null != (entityToken = NextToken(xml, "<m:properties>", "</m:properties>", nextStart, out nextStart)))
{
results = new Hashtable();
var currentObject = new Hashtable();

string propertyToken = null;
int nextPropertyStart = 0;
while (null != (propertyToken = NextToken(xml.Body, "<d:", "</d", nextPropertyStart, out nextPropertyStart)))
while (null != (propertyToken = NextToken(entityToken, "<d:", "</d", nextPropertyStart, out nextPropertyStart)))
{
var parts = propertyToken.Split('>');
if (parts.Length != 2) continue;
var rawvalue = parts[1];
var propertyName = parts[0].Split(' ')[0];

var _ = 0;
var type = NextToken(propertyToken, "m:type=\"", "\"", 0, out _);
if (null == type)
{
{
type = "Edm.String";
}
if (currentObject.Contains(propertyName)) continue;
switch (type)
{
case "Edm.String":
results.Add(propertyName, rawvalue);
currentObject.Add(propertyName, rawvalue);
break;
case "Edm.DateTime":
// not supported
break;
case "Edm.Int64":
results.Add(propertyName, Int64.Parse(rawvalue));
currentObject.Add(propertyName, Int64.Parse(rawvalue));
break;
case "Edm.Int32":
results.Add(propertyName, Int32.Parse(rawvalue));
currentObject.Add(propertyName, Int32.Parse(rawvalue));
break;
case "Edm.Double":
results.Add(propertyName, Double.Parse(rawvalue));
currentObject.Add(propertyName, Double.Parse(rawvalue));
break;
case "Edm.Boolean":
results.Add(propertyName, rawvalue == "true");
currentObject.Add(propertyName, rawvalue == "true");
break;
case "Edm.Guid":
// not supported
break;
}
}
results.Add(currentObject);
}
return results;
}
Expand All @@ -242,6 +269,7 @@ private string NextToken(string xml, string startToken, string endToken, int sta
if (start < 0) return null;
start += startToken.Length;
var end = xml.IndexOf(endToken, start);
if (end < 0) return null;
nextStart = end + endToken.Length;
return xml.Substring(start, end - start);
}
Expand All @@ -258,7 +286,7 @@ private string NextToken(string xml, string startToken, string endToken, int sta
Date + "\n" +
CanonicalizedResource;*/
// Signature=Base64(HMAC-SHA256(UTF8(StringToSign)))
protected string CreateAuthorizationHeader(byte[] content, string contentType, string canonicalResource)
protected string CreateAuthorizationHeader(byte[] content, string canonicalResource)
{
//string toSign = String.Format("{0}\n{1}\n{2}\n{3}\n{4}",
// HttpVerb, hash, contentType, InstanceDate, canonicalResource);
Expand All @@ -272,5 +300,7 @@ protected string CreateAuthorizationHeader(byte[] content, string contentType, s

#endregion
}


}

8 changes: 8 additions & 0 deletions netmfazurestorage/Tests/TableTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public void Run()
this.TestInsertDouble();
this.TestInsertExperimental();
this.QuerySingleEntity();
this.QueryMultipleEntities();
}

private void TestCreate()
Expand Down Expand Up @@ -93,6 +94,13 @@ public void QuerySingleEntity()
Debug.Assert(null != output);
}

public void QueryMultipleEntities()
{
var output = this.client.QueryTable("netmftest", "PartitionKey eq '2'");
Debug.Assert(null != output);
Debug.Assert(output.Count > 0);
}

}

}
Binary file not shown.
Binary file modified netmfazurestorage/obj/Debug/TinyCLR_DebugReferences.cache
Binary file not shown.

0 comments on commit c822d42

Please sign in to comment.