5

I'm trying to create an Azure Function that triggers on an AZ ServiceBus Queue message. The message contains a GUID string, matching the name of a BLOB on AZ storage. I'd like to have that BLOB available through an input binding but I'm not sure how...

I tried :

public static async Task Run(
   [ServiceBusTrigger("outgoing-mail", Connection = "QueueConnString")] string inputMessage,
   [Blob("email-messages/{inputMessage}", FileAccess.Read)] Stream mailBlob,
   [SendGrid(ApiKey = "%SendgridApiKey%")] IAsyncCollector<SendGridMessage> messageCollector,
   ILogger log)

I also tried {serviceBusTrigger} on the blob path by-the-way but either way, I get the following exception :

Microsoft.Azure.WebJobs.Host: Error indexing method 'SendMailQueueWorker'. Microsoft.Azure.WebJobs.Host: Unable to resolve binding parameter 'inputMessage'. Binding expressions must map to either a value provided by the trigger or property of the value the trigger is bound to or must be a system binding expression (e.g. sys.randguid, sys.utcnow, etc.).

I'm sure the input message of the queue is a string, how can I use this message content in the input binding of the BLOB?

[edit]
I added the feature request to UserVoice, so if you're running into this issue as well, please vote! https://feedback.azure.com/forums/355860-azure-functions/suggestions/37528912-combine-servicebus-queue-message-with-storage-inpu
[/edit]

2 Answers 2

6

Looks like this isn't supported for Service Bus Trigger the way it is for Queue Trigger.
You could raise a feature request on UserVoice for this.

But one thing to note is that this limitation holds only for non-JSON messages. If you send a JSON message instead, it will get parsed as documented.

Your function could be something like this

using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace funk_csharp_queue
{
  public class QueueMsg
  {
    public string filename { get; set; }
  }
  public static class ServiceBusTrigger
  {
    [FunctionName("ServiceBusTrigger")]
    public static void Run(
      [ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")] QueueMsg myQueueItem,
      [Blob("samples-workitems/{filename}", FileAccess.Read)] String myBlob,
      ILogger log)
    {
      log.LogInformation($"C# Service Bus trigger function processed: {JsonConvert.SerializeObject(myQueueItem)}");
      log.LogInformation($"C# Blob input read: {myBlob}");
    }
  }
}

And the message you send in the Service Bus Queue / Topic would be something like this

{
  "filename": "11c8f49d-cddf-4b82-a980-e16e8a8e42f8.json"
}

Make sure you set the Content Type to application/json.

Sign up to request clarification or add additional context in comments.

1 Comment

Pretty clear answer there, I'll definitely post it to UserVoice as it seems to be a pretty straight forward and clean solution. Thanks for the info
0

I don't think that's directly possible as you would like to. I would just use a CloudBlobContainer input binding to work around this.

[Blob("email-messages", FileAccess.Read, Connection = "BlobConnectionString")] CloudBlobContainer blobContainer

Then use the blobContainer to read the blob in your function using the inputMessage.

CloudBlob mailBlob = blobContainer.GetBlobReference(inputMessage);

1 Comment

Thanks for your reply! I thought the service bus queue was the way to go, but I used a storage queue instead. It works like a charm with the storage queue trigger. When removing all bindings, the service bus trigger didn't even fire when messages arrived. It think the trigger itself has a couple of bugs... storage queue ftw

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.