Cannot read events from Event Hub

Viewed 27

I am trying to read events from Event Hub using Azure Active Directory. I can successfully write events to my Hub after authenticating, however when reading my program returns 0 events. I can see that my Hub has got messages waiting and If I read from the Hub using the Shared Access Policy URL I can get my messages.

Here is my program:

using System;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.EventHubs;
using Microsoft.Identity.Client;

namespace EventHubsSenderReceiverRbac
{
    class claimInfo
    {
        public string providerID
        {
            get;
            set;
        }
        public string data1
        {
            get;
            set;
        }
        public string patientId
        {
            get;
            set;
        }
    }
    class Program
    {
        static readonly string TenantId = ConfigurationManager.AppSettings["tenantId"];
        static readonly string ClientId = ConfigurationManager.AppSettings["clientId"];
        static readonly string EventHubNamespace = ConfigurationManager.AppSettings["eventHubNamespaceFQDN"];
        static readonly string EventHubName = ConfigurationManager.AppSettings["eventHubName"];
        private const int numOfEvents = 5;

        static async Task Main()
        {
            var ehClient = generateClient();
            Console.WriteLine("Press s to send {0} events\n", numOfEvents);
            Console.WriteLine("Press r to receive events\n");
            Console.WriteLine("Press any other key to exit\n");
            var userInput = Console.ReadKey();
            Console.WriteLine("\n");
            switch (userInput.Key)
            {
                case ConsoleKey.S:
                    await sendEvents(ehClient);
                    break;
                case ConsoleKey.R:
                    await receiveEvents(ehClient);
                    break;
                default:
                    Console.WriteLine("Return");
                    return;
            }
        }

        static EventHubClient generateClient()
        {
            TokenProvider tp = TokenProvider.CreateAzureActiveDirectoryTokenProvider(
              async (audience, authority, state) => {
                  Console.WriteLine("Client ID: {0}", ClientId);
                  Console.WriteLine("Aud: {0}", audience);
                  IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(ClientId)
                    .WithAuthority(authority)
                    .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
                    .Build();
                  Console.WriteLine("App: {0} ", app);

                  var authResult = await app.AcquireTokenForClient(new string[] {
              $"{audience}.default"
                  }).ExecuteAsync();
                  Console.WriteLine("Access Token: {0}", authResult.AccessToken);
                  return authResult.AccessToken;
              },
              $"https://login.microsoftonline.com/{TenantId}");

            var ehClient = EventHubClient.CreateWithTokenProvider(new Uri($"sb://{EventHubNamespace}/"), EventHubName, tp);
            Console.WriteLine("EH Client: {0}", ehClient.ClientId);
            return ehClient;
        }

        static async Task sendEvents(EventHubClient ehClient)
        {
            var clientStub = new claimInfo();
            clientStub.providerID = "provider1";
            clientStub.data1 = "some data";
            clientStub.patientId = "xxxyyy001";

            Console.WriteLine("Sending event");
            for (int i = 1; i <= numOfEvents; i++)
            {
                await ehClient.SendAsync(new EventData(Encoding.UTF8.GetBytes($"{clientStub}")));
            }
            Console.WriteLine("Send done");
            await receiveEvents(ehClient);
        }

        static async Task receiveEvents(EventHubClient ehClient)
        {
            Console.WriteLine("Fetching eventhub description to discover partitions");
            var ehDesc = await ehClient.GetRuntimeInformationAsync();
            Console.WriteLine("ehDesc {0}", ehDesc);
            Console.WriteLine($"Discovered partitions as {string.Join(", ", ehDesc.PartitionIds)}");

            var receiveTasks = ehDesc.PartitionIds.Select(async partitionId => {
                Console.WriteLine($"Initiating receiver on partition {partitionId}");
                var receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, EventPosition.FromEnd());

                while (true)
                {
                    Console.WriteLine("Starting Loop");
                    Console.WriteLine("{0}", receiver.ClientId);
                    Console.WriteLine("{0}", receiver.ConsumerGroupName);
                    Console.WriteLine("{0}", receiver.EventHubClient);
                    Console.WriteLine("Part ID {0}", receiver.PartitionId);
                    var events = await receiver.ReceiveAsync(10, TimeSpan.FromSeconds(120));
                    Console.WriteLine("Event: {0}", events);
                    if (events == null)
                    {
                        Console.WriteLine("Ending Loop");
                        break;
                    }

                    var eventData = events.FirstOrDefault();
                    Console.WriteLine("Events: {0}", events);
                    foreach (EventData c in events)
                    {
                        Console.WriteLine("Data: {0}", Encoding.UTF8.GetString(c.Body.Array));
                    }
                    Console.WriteLine($"Received from partition {partitionId} with message content '" + Encoding.UTF8.GetString(eventData.Body.Array) + "'");
                }

                await receiver.CloseAsync();
            }).ToList<Task>();

            Console.WriteLine("Waiting for receivers to complete");
            await Task.WhenAll(receiveTasks);
            Console.WriteLine("All receivers completed");

            await ehClient.CloseAsync();
            
        }
    }
}

I have modified the sample from here: https://github.com/Azure/azure-event-hubs/blob/master/samples/DotNet/Microsoft.Azure.EventHubs/Rbac/AzureEventHubsSDK/Program.cs

The issue is on line 120 as events is always returned as null.

Am I missing something?

1 Answers

After some digging I found the issue with the above code. When creating a EventHubClient.CreateReceiver object you need to provide a EventPosition. In the above code this was set to EventPosition.FromEnd(), which states that:

Returns the position for the end of a stream. Provide this position in receiver creation to start receiving from the next available event in the partition after the receiver is created.

As my CreateReceiver was being initialized after the events were published to the Hub, they were not found.

Related