public async Task InspectPartition()
        {
            #region Snippet:EventHubs_Sample03_InspectPartition

            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup    = EventHubConsumerClient.DefaultConsumerGroupName;
            /*@@*/
            /*@@*/ connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            /*@@*/ eventHubName     = _scope.EventHubName;

            var consumer = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName);

            try
            {
                string[] partitions = await consumer.GetPartitionIdsAsync();

                string firstPartition = partitions.FirstOrDefault();

                PartitionProperties partitionProperties = await consumer.GetPartitionPropertiesAsync(firstPartition);

                Debug.WriteLine($"Partition: { partitionProperties.Id }");
                Debug.WriteLine($"\tThe partition contains no events: { partitionProperties.IsEmpty }");
                Debug.WriteLine($"\tThe first sequence number is: { partitionProperties.BeginningSequenceNumber }");
                Debug.WriteLine($"\tThe last sequence number is: { partitionProperties.LastEnqueuedSequenceNumber }");
                Debug.WriteLine($"\tThe last offset is: { partitionProperties.LastEnqueuedOffset }");
                Debug.WriteLine($"\tThe last enqueued time is: { partitionProperties.LastEnqueuedTime }, in UTC.");
            }
            finally
            {
                await consumer.CloseAsync();
            }

            #endregion
        }
        // Get the number of unprocessed events by deriving the delta between the server side info and the partition lease info,
        private static long GetUnprocessedEventCount(PartitionProperties partitionInfo, BlobsCheckpointStore.BlobStorageCheckpoint partitionLeaseInfo)
        {
            long partitionLeaseInfoSequenceNumber = partitionLeaseInfo.SequenceNumber ?? 0;

            // This handles two scenarios:
            //   1. If the partition has received its first message, Offset will be null and LastEnqueuedSequenceNumber will be 0
            //   2. If there are no instances set to process messages, Offset will be null and LastEnqueuedSequenceNumber will be >= 0
            if (partitionLeaseInfo.Offset == null && partitionInfo.LastEnqueuedSequenceNumber >= 0)
            {
                return(partitionInfo.LastEnqueuedSequenceNumber + 1);
            }

            if (partitionInfo.LastEnqueuedSequenceNumber > partitionLeaseInfoSequenceNumber)
            {
                return(partitionInfo.LastEnqueuedSequenceNumber - partitionLeaseInfoSequenceNumber);
            }

            // Partition is a circular buffer, so it is possible that
            // LastEnqueuedSequenceNumber < SequenceNumber
            long count = 0;

            unchecked
            {
                count = (long.MaxValue - partitionInfo.LastEnqueuedSequenceNumber) + partitionLeaseInfoSequenceNumber;
            }

            // It's possible for checkpointing to be ahead of the partition's LastEnqueuedSequenceNumber,
            // especially if checkpointing is happening often and load is very low.
            // If count is negative, we need to know that this read is invalid, so return 0.
            // e.g., (9223372036854775807 - 10) + 11 = -9223372036854775808
            return((count < 0) ? 0 : count);
        }
        public async Task ReadPartitionFromSequence()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample05_ReadPartitionFromSequence

#if SNIPPET
            var connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName     = "<< NAME OF THE EVENT HUB >>";
#else
            var connectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName     = scope.EventHubName;
#endif
            var consumerGroup = EventHubConsumerClient.DefaultConsumerGroupName;

            var consumer = new EventHubConsumerClient(
                consumerGroup,
                connectionString,
                eventHubName);

            try
            {
                using CancellationTokenSource cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));

                string firstPartition          = (await consumer.GetPartitionIdsAsync(cancellationSource.Token)).First();
                PartitionProperties properties = await consumer.GetPartitionPropertiesAsync(firstPartition, cancellationSource.Token);

                EventPosition startingPosition = EventPosition.FromSequenceNumber(properties.LastEnqueuedSequenceNumber);

                await foreach (PartitionEvent partitionEvent in consumer.ReadEventsFromPartitionAsync(
                                   firstPartition,
                                   startingPosition,
                                   cancellationSource.Token))
                {
                    string readFromPartition = partitionEvent.Partition.PartitionId;
                    byte[] eventBodyBytes    = partitionEvent.Data.EventBody.ToArray();

                    Debug.WriteLine($"Read event of length { eventBodyBytes.Length } from { readFromPartition }");
                }
            }
            catch (TaskCanceledException)
            {
                // This is expected if the cancellation token is
                // signaled.
            }
            finally
            {
                await consumer.CloseAsync();
            }

            #endregion
        }
Example #4
0
        public async Task SendDoesNotUpdatePartitionPropertiesWhenSendingToDifferentPartition()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(2))
            {
                var connectionString = TestEnvironment.BuildConnectionStringForEventHub(scope.EventHubName);

                await using (var client = new EventHubClient(connectionString))
                {
                    var partitionIds = await client.GetPartitionIdsAsync();

                    EventData[] events = new[] { new EventData(Encoding.UTF8.GetBytes("I should not update stuff")) };

                    await using (EventHubProducer producer0 = client.CreateProducer(new EventHubProducerOptions {
                        PartitionId = partitionIds[0]
                    }))
                        await using (EventHubProducer producer1 = client.CreateProducer(new EventHubProducerOptions {
                            PartitionId = partitionIds[1]
                        }))
                        {
                            // Sending events beforehand so the partition has some information.

                            await producer0.SendAsync(events);

                            PartitionProperties oldPartitionProperties = await client.GetPartitionPropertiesAsync(partitionIds[0]);

                            Assert.That(oldPartitionProperties, Is.Not.Null, "A set of partition properties should have been returned.");

                            await producer1.SendAsync(events);

                            PartitionProperties newPartitionProperties = await client.GetPartitionPropertiesAsync(partitionIds[0]);

                            Assert.That(newPartitionProperties, Is.Not.Null, "A set of partition properties should have been returned.");

                            // All properties should remain the same.

                            Assert.That(newPartitionProperties.Id, Is.EqualTo(oldPartitionProperties.Id));
                            Assert.That(newPartitionProperties.EventHubName, Is.EqualTo(oldPartitionProperties.EventHubName));
                            Assert.That(newPartitionProperties.BeginningSequenceNumber, Is.EqualTo(oldPartitionProperties.BeginningSequenceNumber));
                            Assert.That(newPartitionProperties.LastEnqueuedSequenceNumber, Is.EqualTo(oldPartitionProperties.LastEnqueuedSequenceNumber));
                            Assert.That(newPartitionProperties.LastEnqueuedOffset, Is.EqualTo(oldPartitionProperties.LastEnqueuedOffset));
                        }
                }
            }
        }
        /// <summary>
        ///   Runs the sample using the specified Event Hubs connection information.
        /// </summary>
        ///
        /// <param name="connectionString">The connection string for the Event Hubs namespace that the sample should target.</param>
        /// <param name="eventHubName">The name of the Event Hub, sometimes known as its path, that she sample should run against.</param>
        ///
        public async Task RunAsync(string connectionString,
                                   string eventHubName)
        {
            // To interact with an Event Hubs, a client is needed.  There are clients associated with each of the core areas of functionality
            // with an Event Hub, naming publishing events and consuming events.  Each of these clients manages resources and should be
            // explicitly closed or disposed, but it is not necessary to do both.
            //
            // In this example, we will create a producer client and use it to inspect the properties of an Event Hub.  When complete, we take
            // advantage of the new asynchronous dispose to ensure that clean-up is performed when we are done or when an exception is encountered.

            await using (var producerClient = new EventHubProducerClient(connectionString, eventHubName))
            {
                // Using the client, we will inspect the Event Hub that it is connected to, getting
                // access to its informational properties.

                EventHubProperties properties = await producerClient.GetEventHubPropertiesAsync();

                Console.WriteLine("The Event Hub has the following properties:");
                Console.WriteLine($"\tThe path to the Event Hub from the namespace is: { properties.Name }");
                Console.WriteLine($"\tThe Event Hub was created at: { properties.CreatedOn.ToString("yyyy-MM-dd hh:mm:ss tt (zzz)") }, in UTC.");
                Console.WriteLine();

                // Partitions of an Event Hub are an important concept.  Using the Event Hub properties, we'll inspect each of its partitions,
                // getting access to partition-level properties.

                foreach (string partitionId in properties.PartitionIds)
                {
                    PartitionProperties partitionProperties = await producerClient.GetPartitionPropertiesAsync(partitionId);

                    Console.WriteLine($"\tPartition: { partitionProperties.Id }");
                    Console.WriteLine($"\t\tThe partition contains no events: { partitionProperties.IsEmpty }");
                    Console.WriteLine($"\t\tThe first sequence number of an event in the partition is: { partitionProperties.BeginningSequenceNumber }");
                    Console.WriteLine($"\t\tThe last sequence number of an event in the partition is: { partitionProperties.LastEnqueuedSequenceNumber }");
                    Console.WriteLine($"\t\tThe last offset of an event in the partition is: { partitionProperties.LastEnqueuedOffset }");
                    Console.WriteLine($"\t\tThe last time that an event was enqueued in the partition is: { partitionProperties.LastEnqueuedTime.ToString("yyyy-MM-dd hh:mm:ss tt (zzz)") }, in UTC.");
                    Console.WriteLine();
                }
            }

            // At this point, our client has passed its "using" scope and has safely been disposed of.  We have no
            // further obligations.

            Console.WriteLine();
        }
Example #6
0
        public async Task SendUpdatesPartitionProperties()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestEnvironment.BuildConnectionStringForEventHub(scope.EventHubName);

                await using (var client = new EventHubClient(connectionString))
                {
                    var         partition = (await client.GetPartitionIdsAsync()).First();
                    EventData[] events    = new[] { new EventData(Encoding.UTF8.GetBytes("I should update stuff")) };

                    await using (EventHubProducer producer = client.CreateProducer(new EventHubProducerOptions {
                        PartitionId = partition
                    }))
                    {
                        // Sending events beforehand so the partition has some information.

                        await producer.SendAsync(events);

                        PartitionProperties oldPartitionProperties = await client.GetPartitionPropertiesAsync(partition);

                        Assert.That(oldPartitionProperties, Is.Not.Null, "A set of partition properties should have been returned.");

                        await producer.SendAsync(events);

                        PartitionProperties newPartitionProperties = await client.GetPartitionPropertiesAsync(partition);

                        Assert.That(newPartitionProperties, Is.Not.Null, "A set of partition properties should have been returned.");

                        // The following properties should not have been altered.

                        Assert.That(newPartitionProperties.Id, Is.EqualTo(oldPartitionProperties.Id));
                        Assert.That(newPartitionProperties.EventHubName, Is.EqualTo(oldPartitionProperties.EventHubName));
                        Assert.That(newPartitionProperties.BeginningSequenceNumber, Is.EqualTo(oldPartitionProperties.BeginningSequenceNumber));

                        // The following properties should have been updated.

                        Assert.That(newPartitionProperties.LastEnqueuedSequenceNumber, Is.GreaterThan(oldPartitionProperties.LastEnqueuedSequenceNumber));
                        Assert.That(newPartitionProperties.LastEnqueuedOffset, Is.GreaterThan(oldPartitionProperties.LastEnqueuedOffset));
                    }
                }
            }
        }
        public async Task ClientCanRetrievePartitionProperties(TransportType transportType)
        {
            var partitionCount = 4;

            await using (EventHubScope scope = await EventHubScope.CreateAsync(partitionCount))
            {
                var clientOptions    = new EventHubClientOptions();
                var connectionString = TestEnvironment.BuildConnectionStringForEventHub(scope.EventHubName);
                ConnectionStringProperties connectionProperties = ConnectionStringParser.Parse(connectionString);

                var credential = new SharedAccessSignatureCredential
                                 (
                    new SharedAccessSignature
                    (
                        $"{ clientOptions.TransportType.GetUriScheme() }://{ connectionProperties.Endpoint.Host }/{ connectionProperties.EventHubName }".ToLowerInvariant(),
                        connectionProperties.SharedAccessKeyName,
                        connectionProperties.SharedAccessKey,
                        TimeSpan.FromHours(4)
                    )
                                 );

                await using (var client = new EventHubClient(connectionProperties.Endpoint.Host, connectionProperties.EventHubName, credential, new EventHubClientOptions {
                    TransportType = transportType
                }))
                {
                    var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(20));
                    EventHubProperties properties = await client.GetPropertiesAsync();

                    var partition = properties.PartitionIds.First();
                    PartitionProperties partitionProperties = await client.GetPartitionPropertiesAsync(partition, cancellation.Token);

                    Assert.That(partitionProperties, Is.Not.Null, "A set of partition properties should have been returned.");
                    Assert.That(partitionProperties.Id, Is.EqualTo(partition), "The partition identifier should match.");
                    Assert.That(partitionProperties.EventHubName, Is.EqualTo(connectionProperties.EventHubName).Using((IEqualityComparer <string>)StringComparer.InvariantCultureIgnoreCase), "The Event Hub path should match.");
                    Assert.That(partitionProperties.BeginningSequenceNumber, Is.Not.EqualTo(default(long)), "The beginning sequence number should have been populated.");
                    Assert.That(partitionProperties.LastEnqueuedSequenceNumber, Is.Not.EqualTo(default(long)), "The last sequence number should have been populated.");
                    Assert.That(partitionProperties.LastEnqueuedOffset, Is.Not.EqualTo(default(long)), "The last offset should have been populated.");
                }
            }
        }