Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I configure an Azure Function triggered by Service Bus with a custom INameResolver? #345

Closed
tjrobinson opened this issue Jun 19, 2017 · 18 comments
Labels

Comments

@tjrobinson
Copy link

I want to be able to control the name of the Service Bus Queue or Subscription that my Azure Function reads from at run-time.

With WebJobs (which Azure Functions are based on) you could do this by implementing and configuring a custom INameResolver, see: https://stackoverflow.com/questions/33860550/how-to-have-a-configuration-based-queue-name-for-web-job-processing

However, with Azure functions I have no access to JobHostConfiguration to wire up this custom resolver.

Can I still use an INameResolver, and if so how?

Cross-posted to https://stackoverflow.com/questions/44625782/how-can-i-configure-an-azure-function-triggered-by-service-bus-with-a-custom-ina

Thanks!

@brettsam
Copy link
Member

I'm linking this to Azure/azure-functions-host#1579 -- we can start treating that as our tracking issue for a 'Dependency Injection' solution.

@lindydonna
Copy link
Contributor

@tjrobinson
Copy link
Author

@lindydonna Thanks, I've added a comment to that article, perhaps you could have a look rather than me duplicating it here?

@lindydonna
Copy link
Contributor

@tjrobinson That's a good question, I don't know the answer. @brettsam could you reply?

@tjrobinson
Copy link
Author

@brettsam Any chance of your help with this?

How can I set the subscription name when using Binder for the input of a Service Bus triggered function?

I can set the topic name using ServiceBusAttribute and the account using ServiceBusAccountAttribute but can't see any way to set the subscription name.

Is it supported or not?

This is the code I have so far:

    public static class ProcessEventUpdateFunction
    {
        [FunctionName("ProcessEventUpdate")]
        public static async Task Run(Binder binder, TraceWriter log)
        {
            string topicName = ("eventupdates" + Environment.MachineName).ToLowerInvariant();

            var attributes = new Attribute[]
            {
                new ServiceBusAccountAttribute("AzureWebJobsServiceBus"),
                new ServiceBusAttribute(topicName, AccessRights.Listen),
            };

            string message = await binder.BindAsync<string>(attributes);

Before I had this, but it didn't allow the topic name to be customised at runtime:

    public static class ProcessEventUpdateFunction
    {
        // When running locally, change "eventupdates" to "eventupdatesYOURMACHINENAME" to avoid sharing the same topic as others

        [FunctionName("ProcessEventUpdate")]
        public static async Task Run([ServiceBusTrigger("eventupdates", "casemanager", AccessRights.Listen)]string message, TraceWriter log)
        {

@ichivers
Copy link

@tjrobinson I tried that and it didn't work:

 public static async void Run(Binder binder, TraceWriter log)
        {
            var attributes = new Attribute[]
            {                
                new QueueTriggerAttribute("rmslogqueue"){ Connection = "StorageConnectionString" }                     
            };
            LogEntry logQueueItem = await binder.BindAsync<LogEntry>(attributes);

@tjrobinson
Copy link
Author

@ichivers That's the problem, it doesn't work. My code is just my attempt so far.

@tjrobinson
Copy link
Author

@lindydonna, @brettsam, anyone - please could you help with this?

All I want to do is be able to use C# code to determine the name of my Service Bus topic name at runtime.

I've looked at all the documentation I can find but nothing covers this.

My latest attempt:

{
  "$schema": "http://json.schemastore.org/function",
  "disabled": false,
  "scriptFile": "..\\bin\\Debug\\net462\\bin\\MyApp.AzureFunctions.dll",
  "entryPoint": "MyApp.AzureFunctions.ProcessPendingPublish.ProcessPendingPublishFunction.Run",
  "configurationSource": "attributes",
  "bindings": [
    {
      "name": "ProcessPendingPublish",
      "type": "serviceBusTrigger",
      "dataType": "string",
      "connection": "MyConnection"
    }
  ]
}
public static async Task Run([ServiceBusTrigger(topicName: "pendingpublish", subscriptionName: "casemanager", access: AccessRights.Listen, Connection = "MyConnection")]string message, Binder binder, TraceWriter log)

string topicName = "pendingpublish";

            if (ConfigurationHelper.IsDevelopment())
            {
                topicName += Environment.MachineName.ToLowerInvariant();
            }

            string subscriptionName = "casemanager";
            var access = AccessRights.Listen;

            var serviceBusTriggerAttribute = new ServiceBusTriggerAttribute(topicName, subscriptionName, access)
            {
                Connection = "MyConnection"
            };

            var input = await binder.BindAsync<string>(serviceBusTriggerAttribute);

This errors with:

No binding found for attribute 'Microsoft.Azure.WebJobs.ServiceBusTriggerAttribute'.

@tjrobinson
Copy link
Author

This gets me close, but I still need to edit a file rather than making it dynamic:

App settings are resolved whenever a value is enclosed in percent signs, such as %MyAppSetting%. Note that the connection property of triggers and bindings is a special case and automatically resolves values as app settings.
https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#resolving-app-settings

@zsmorris
Copy link

@tjrobinson, @lindydonna, @brettsam Anyone find an answer for @tjrobinson? We have the exact same situation: Configure a Service Bus topic name trigger at runtime (and also subscription filter, hopefully).

Abandoning trying to use a Service Bus trigger and wrapping a C# Service Bus client in a Durable function would probably be a work-around, but that's not nearly as clean as being able to change the trigger configuration at runtime.

Thanks!

@tjrobinson
Copy link
Author

@zsmorris Take a look a this extremely useful blog post: https://blog.wille-zone.de/post/azure-functions-dependency-injection/

I've used the above to successfully inject other dependencies, just not the specific one in my original post yet (due to lack of time and other priorities).

Though I'm going off Azure Functions and will probably be migrating to Web Jobs soon, due to this issue: Azure/azure-functions-host#992 (comment)

@zsmorris
Copy link

Thank you, @tjrobinson. Some sobering caveats discussed there.

@IshamMohamed
Copy link

@jack0fshad0ws
Copy link

2 years later and no solution?

@IshamMohamed
Copy link

2 years later and no solution?

as suggested by @tjrobinson you can use dependency injection

@tjrobinson
Copy link
Author

This is quite an old issue and I suspect it's no longer a problem in Azure Functions 3. You might also like to try FunctionMonkey which sits on top of Azure Functions: https://functionmonkey.azurefromthetrenches.com/guides/serviceBus/topics.html

@rkv2751989
Copy link

Someone Please suggest, Can we pass dynamic connection in Azure service bus trigger in Azure Function 3 or only approach is need to be use FunctionMonkey.

@BrianVallelunga
Copy link

I'm also curious if we can make dynamic service bus input bindings. I'll look at the FunctionMonkey, but if this is doable without that dependency, I'd like to know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants