1
votes

I noticed that, all of the sudden, Topics are no longer available as part of Service Bus. Is it possible to write a message to an Event Grid Topic within an Azure Function?

3

3 Answers

3
votes

The following code snippet is an example of the using an azure function for pushing a telemetry stream to the eventing model:

enter image description here

#r "Microsoft.ServiceBus"
#r "Newtonsoft.Json"


using System.Configuration;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ServiceBus.Messaging;
using Newtonsoft.Json;

// reusable client proxy
static HttpClient client = HttpClientHelper.Client(ConfigurationManager.AppSettings["TopicEndpointEventGrid"], ConfigurationManager.AppSettings["aeg-sas-key"]);

// AF
public static async Task Run(EventData ed, TraceWriter log)
{
    log.Info($"C# Event Hub trigger function processed a message:{ed.SequenceNumber}"); 
    //foreach(var prop in ed.SystemProperties)
    //   log.Info($"{prop.Key} = {prop.Value}");

    // fire EventGrid Custom Topic
    var egevent = new 
    {
        Id = ed.SequenceNumber.ToString(),
        Subject = $"/iothub/events/{ed.SystemProperties["iothub-message-source"] ?? "?"}/{ed.SystemProperties["iothub-connection-device-id"] ?? "?"}",
        EventType = "telemetryDataInserted",
        EventTime = ed.EnqueuedTimeUtc,
        Data = new
        {
            sysproperties = ed.SystemProperties,
            properties = ed.Properties,
            body = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(ed.GetBytes()))
        }
    };
    await client.PostAsJsonAsync("", new[] { egevent });  
}

// helper
class HttpClientHelper
{
    public static HttpClient Client(string address, string key)
    {      
        var client = new HttpClient() { BaseAddress = new Uri(address) };
        client.DefaultRequestHeaders.Add("aeg-sas-key", key);
        return client;      
    }
}

the function.json:

    {
      "bindings": [
       {
         "type": "eventHubTrigger",
         "name": "ed",
         "direction": "in",
         "path": "myIoTHubName",
         "connection": "connectionstringIOTHUB",
         "consumerGroup": "eventing",
         "cardinality": "many"
        }
      ],
      "disabled": false
    }

Note, that the payload for the AEG Custom Topic is depended from its inputSchema property. Basically, current AEG version (included also preview) allows to declare an input schema from the following selection:

  • EventGridSchema (default schema)
  • CloudEventV01Schema
  • CustomEventSchema (still in the preview)

more details can be found:

2
votes

Here is the way to connect to Azure event grid topic in Azure function via Visual Studio code. NOTE: I didn't have to add any function.json file.

Since Topic is just like an API with URL create an HTTP client pointing to your event data grid topic's URL add the topic's Access key to the HTTP client header.

HttpClient client = new HttpClient() { 
   BaseAddress = new Uri(<YOUR_TOPIC_URL>) 
};
client.DefaultRequestHeaders.Add("aeg-sas-key", "<YOUR_TOPIC_KEY>");

var egevent = new
{
   Id = 1234,
   Subject = "SendEmail",
   EventType = "SendEmail",
   EventTime = DateTime.UtcNow,
   Data = <YOUR_MESSAGE>(Could be anything and object or data literals)
};
var x = await client.PostAsJsonAsync("", new[] { egevent });
log.LogInformation(x.ReasonPhrase);

Hopefully, this helps.

2
votes

You can do this easily using the Azure Event Grid Nuget package:

var failedEvent = new EventGridEvent()
        {
            Id = Guid.NewGuid().ToString(),
            Subject = "create-tenant-failed",
            EventType = "create-tenant-failed",
            EventTime = DateTime.UtcNow,
            Data = reason,
            DataVersion = "1.0"
        };

        var topicHostname = new Uri(FailedEventTopicUrl).Host;
        var topicCredentials = new TopicCredentials("my-access-token-from-azure-portal");
        var client = new EventGridClient(topicCredentials);

        await client.PublishEventsAsync(topicHostname, new List<EventGridEvent>() { failedEvent });