Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send data to Service Bus Topic with Azure Functions?

I have default C# based HTTP Trigger here and I wish to send data "Hello Name" to Service Bus Topic (already created). I'm coding at portal.

How to do it Service Bus output binding?

This is not working. Any help available?

-Reference missing for handling Service Bus?

-How to define Connection of service bus? Where is Functions.json

-How to send a message to service bus?

//This FunctionApp get triggered by HTTP and send message to Azure Service Bus

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Company.Function

{
    public static class HttpTriggerCSharp1
{
    [FunctionName("HttpTriggerCSharp1")]
    [return: ServiceBus("myqueue", Connection = "ServiceBusConnection")] // I added this for SB Output. Where to define.

    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
        ILogger log)

    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        string name = req.Query["name"];
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;
        string responseMessage = string.IsNullOrEmpty(name)
            ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
            : $"Hello, {name}. This HTTP triggered function executed successfully.";
        return new OkObjectResult(responseMessage);
        // I added this for SB Output
        return responseMessage;
    }
}

}

like image 451
Kenny_I Avatar asked Mar 09 '20 20:03

Kenny_I


2 Answers

Firstly, there are two bindings to send data to service bus. Firstly is what you show, using the return binding, after install two packages Microsoft.Azure.WebJobs.Extensions.ServiceBus and WindowsAzure.ServiceBus, then you will be able to send data. And you could not do it cause your function type is IActionResult and you are trying to return string(responseMessage).

So if you want to send the whole responseMessage, just return new OkObjectResult(responseMessage);, it will work. And the result would be like below pic.

enter image description here

And if you want to use return responseMessage; should change your method type to string, it will be public static async Task<string> RunAsync and result will be below.

enter image description here

Another binding you could refer to below code or this sample.

[FunctionName("Function1")]
        [return: ServiceBus("myqueue", Connection = "ServiceBusConnection")]
        public static async Task RunAsync(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            [ServiceBus("myqueue", Connection = "ServiceBusConnection")] MessageSender messagesQueue,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            byte[] bytes = Encoding.ASCII.GetBytes(responseMessage);
            Message m1 = new Message(bytes);
            await messagesQueue.SendAsync(m1);

        }

How to define Connection of service bus? Where is Functions.json

In the local you should define the connection in the local.settings.jon, you could use any name with the connection, then in the binding Connection value should be the name you set in the json file. And cause you are using c#, so you could not modify the function.json file, there will be a function.json file in the debug folder. So you could only change the binding in the code.

Hope this could help you, if you still have other problem , please feel free to let me know.

like image 122
George Chen Avatar answered Sep 22 '22 08:09

George Chen


Make sure you first install Microsoft.Azure.WebJobs.Extensions.ServiceBus NuGet package. Then make sure you are using it in your project:

using Microsoft.Azure.WebJobs.Extensions.ServiceBus;

Make sure you clean and build the project to make sure you have no errors.

Then you need to make sure you have a "ServiceBusConnection" connection string inside your local.settings.json file:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "ServiceBusConnection": "Endpoint=sb://...",
  }
}

Which you can get if you go to Azure portal -> Service bus namespace -> Shared access policies -> RootManageSharedAccessKey -> Primary Connection String. Copy and paste this connection string inside "ServiceBusConnection". You can also use the Secondary Connection String as well.

Note: Service bus queues/topics have shared access policies as well. So if you don't want to use the Service bus namespace level access policies, you can create one at queue/topic level, so you your function app only has access to the queue/topic defined in your namespace.

Also if you decide to publish your function app, you will need to make sure you create a configuration application setting for "ServiceBusConnection", since local.settings.json is only used for local testing.

like image 26
RoadRunner Avatar answered Sep 22 '22 08:09

RoadRunner