0
votes

I'm having an issue with an Azure Service Bus output binding that I'm uncertain about how to proceed with. I've had no luck finding a similar question, so I apologize if this is a duplicate.

I'm trying to use the local VS 2017 development process, so the function.json bindings should be generated automatically. The function signature is as follows:

  [FunctionName("RequestNewPaladinInvitation")]
  public static HttpResponseMessage Run(
     [HttpTrigger(AuthorizationLevel.Anonymous, "post")]HttpRequestMessage req,
     [ServiceBus("thequeue")] ICollector<Invitation> invitationOutputQueue,
     TraceWriter log)
  {
     //Do some stuff and write to the queue
     invitationOutputQueue.Add(invite);
  }

I get the following error when running the function locally.

Microsoft.Azure.WebJobs.Host: Error indexing method 'RequestNewPaladinInvitation.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'invitationOutputQueue' to type ICollector`1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.). [9/1/2017 5:42:49 PM] Error indexing method 'RequestNewPaladinInvitation.Run'

Both my host.json and local.settings.json are defined as follows:

{
   "IsEncrypted": false,
   "Values": {
      "AzureWebJobsStorage": "<MyStorageAccountInfo>",
      "AzureWebJobsDashboard": "<MyDashboardInfo>",
      "AzureWebJobsServiceBus": "<MyServiceBusConnectionString>"
   }
}

I was under the impressing that defining the AzureWebJobsServiceBus value would make that the default ServiceBusAccount for any ServiceBus bindings throughout the function app.

I also tried explicitly pointing the ServiceBus binding to the connection string for the account with the following alternative attribute [ServiceBus("createpaladininvitation",Connection = "ServiceBus")]. My understanding of the convention is that the AzureWebJobs portion of the property should not be included. Just in case I misunderstood, I tried [ServiceBus("createpaladininvitation",Connection = "AzureWebJobsServiceBus")] as well. I even tried to decorate both the method and parameter with the following attribute, [ServiceBusAccount("ServiceBus")]. I also tried the same variations as with the Connection parameter for the ServiceBus attribute.

In all cases, I get the same function.json output, which shows no binding generated for the ServiceBus output binding.

Here's the function.json:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "methods": [
        "post"
      ],
      "authLevel": "anonymous",
      "name": "req"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\AzureFunctionsPoc.dll",
  "entryPoint": "AzureFunctionsPoc.RequestNewPaladinInvitation.Run"
}

It feels like I'm missing something obvious.

[Update]

As I tried to continue to figure out what's going on, I ran the function locally and edited the generated function.json file and added the binding that I think should have been generated. The resulting manually edited function.json is:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "methods": [
        "post"
      ],
      "authLevel": "anonymous",
      "name": "req"
    },
    {
      "type": "serviceBus",
      "name": "invitationOutputQueue",
      "queueName": "createpaladininvitation",
      "connection": "ServiceBus",
      "direction": "out"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\AzureFunctionsPoc.dll",
  "entryPoint": "AzureFunctionsPoc.RequestNewPaladinInvitation.Run"
}

With those edits, the method works exactly as expected.

This feels even more like either a syntax or convention issue that I'm missing, or a tooling bug.

1
Seems similar to this questionMikhail Shilkov
@Mikhail - I took a quick look at the question you linked to. It did seem similar. Unlike that question, however, in my case, changing the Trigger type didn't seem to make any difference. Thank you, however, for pointing it out.Steve Brouillard

1 Answers

3
votes

There is currently an outstanding tooling bug in regards to ServiceBus output triggers. It will work if you 'deploy' your app to Azure Functions, just not locally with the tooling

Please see relevant GitHub issues here: Service Bus output binding issue

and here: Latest v1.0.0 not working with ServiceBus. alpha 6 still works.

This is related to the lazy load. We're not picking up the service bus extension, hence the indexing error. (Azure/azure-webjobs-sdk-script#1637)

The reason for that is that ServiceBus extension is different than the others. We expect extensions to have a public parameterless config object that implements IExtensionConfigProvider.

SB is internal (https://github.com/Azure/azure-webjobs-sdk/blob/663a508e8a851629c26a51e7de3af36629dfd120/src/Microsoft.Azure.WebJobs.ServiceBus/Config/ServiceBusExtensionConfig.cs#L17 ) so our scan for ExportedTypes misses it (see https://github.com/Azure/azure-webjobs-sdk-script/blob/b1445485807bb190ba0716af1a8dc81a864b5228/src/WebJobs.Script/Host/ScriptHost.cs#L735) . SB's config does not have a parameterless ctor, so the Activator.createInstance call will fail too. This hotfix (which we made to script runtime) Azure/azure-webjobs-sdk-script#1804 would fix it; but that would need to be pulled to CLI.