1
votes

Im looking to write an Azure function that takes in a message from IoTHub and places it on a Service bus queue based on data in the message. The thing is, the queue name will changed based on the parameters of the message and the documentation I’ve looked at, such as this all set the queue name as part of the output settings. Has anyone done anything similar or have any code samples to write to a queue based upon a value in the incoming message? I'm trying to set a function up but it wont even let me set the output type to service bus and not put the queue name in, which I can't, as it isn't fixed!

So if the input was:

{
    “queue”: “MyQ12345”,
    “data”: “some data here”
}

The function should write the data field (or the entire incoming message) to the service bus queue “MyQ12345” which already exists on the same subscription/resource group etc. Thanks

EDIT1: Here's what I've got thus far:

So I've tried what @Mikhail has suggested, here is what I'm doing:

run.csx

using System;

public static string Run(MyPoco myEventHubMessage, TraceWriter log, out string queue)
{
    var queueName = myEventHubMessage.QueueName;
    queue = queueName;
    log.Info($"<IoT Hub => ServiceBus> C# Event Hub trigger function processed a message: {queueName}");
    return QueueName;
}

public class MyPoco
{
  public string QueueName { get; set; }
  public double Other { get; set; }
  public double Props { get; set; }
  public int Here { get; set; }
}

function.json:

{
      "type": "serviceBus",
      "name": "$return",
      "direction": "out",
      "queueName": "{queue}",
      "connection": "ServiceBusConnectionString",
      "accessRights": "manage"
}

but this gives me the following error:

Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'queue' to type String&. Make sure the parameter Type is supported by the binding.

2

2 Answers

3
votes

You can define a class to make your message strongly typed:

public class MyItem
{
    public string Queue { get; set; }
    public string Data { get; set; }
}

then accept it as function input parameter:

public string Run(MyItem item)
{
    return item.Data;
}

and define the output binding like this:

{
    "type": "serviceBus",
    "name": "$return",
    "queueName": "{queue}",
    "connection": "...",
    "accessRights_": "Manage",
    "direction": "out"
}
1
votes

Another way to do is use the custom endpoints and message routing for Azure IoT Hub and directly have the messages sent to the SB queue of your choice from IoT Hub without passing through a Function.

For now IoT Hub routing only works on message properties, not yet on the messages body (which is in the plan of record) but you can put the queue name in a message property and simply define a query to route the messages to the right queue based on this property. There are some limitations such as the number of custom endpoints you can set for IoT Hub as well as predefine what the queues should be, but depending on your scenario that could work for you.