0
votes

I am using Azure functions with my Iot Hub event hub based messages. The messages are coming in via a JSON array. I am able to parse the JSON array no problem, and get the message EventData (to get the DeviceId), and the message body. When a message comes in, I want to create a table with the DeviceId as the name, the partition key will be the name field from each item in the JSON array, and then I was going to use the "time" for the row key. This way I can pull the data from whatever device I want, and whatever signal (signified by the "name" field in the JSON object). I can then use the rowkey to get only the rows between two dates.

The problem I'm having right now is that I get an error

The name 'CloudStorageAccount' does not exist in the current context

I read that there are some versioning issues for Microsoft.WindowsAzure.Storage but I don't know where/how to fix it.

My code:

#r "Newtonsoft.Json"
#r "Microsoft.ServiceBus"
#r "Microsoft.WindowsAzure.Storage"

using Microsoft.ServiceBus.Messaging;
using System;



public static void Run(EventData myEventHubMessage, TraceWriter log)
{
    var CloudObject = new DeviceEventList();
    var deviceId = GetDeviceId(myEventHubMessage);
    var myMessageBody = GetPayload(myEventHubMessage.GetBytes());
    CloudObject = Newtonsoft.Json.JsonConvert.DeserializeObject<DeviceEventList>(myMessageBody);
    log.Info($"C# Event Hub trigger function processed a message: deviceId: {deviceId}");
    var storageAccount = CloudStorageAccount.Parse(System.Environment.GetEnvironmentVariable("Storage", EnvironmentVariableTarget.Process));  
    var tableClient = storageAccount.CreateCloudTableClient();  
    var cloudTable = tableClient.GetTableReference(deviceId);  
    cloudTable.CreateIfNotExists();


    foreach(var data in CloudObject.devicetelemetry)
    {
    log.Info($"C# Event Hub trigger function processed a message: name: {data.name}");
    }


}

public class DeviceEventData
{
    public string name{get;set;}
    public string time{get;set;}
    public string val{get;set;}
}

private static string GetPayload(byte[] body)
{
    var json = System.Text.Encoding.UTF8.GetString(body);
    return json;
}

private static string GetDeviceId(EventData message)
{
    return message.SystemProperties["iothub-connection-device-id"].ToString();
}

public class DeviceEventList
{
    public List<DeviceEventData> devicetelemetry {get;set;}
}

If I comment out the lines below, the function parses the message and prints out the name of each JSON object as expected.

    var storageAccount = CloudStorageAccount.Parse(System.Environment.GetEnvironmentVariable("Storage", EnvironmentVariableTarget.Process));  
    var tableClient = storageAccount.CreateCloudTableClient();  
    var cloudTable = tableClient.GetTableReference(deviceId);  
    cloudTable.CreateIfNotExists();

Is there something special I have to do to use Azure storage tables in this way? I don't think I can use output binding to a table because I need the name of the table to be dynamic based on the deviceId.

1

1 Answers

1
votes

With #r "Microsoft.WindowsAzure.Storage" you are adding the reference to Microsoft.WindowsAzure.Storage, however, you are not including it. Try adding:

using Microsoft.WindowsAzure.Storage;