예제 #1
0
        private static async Task <IEventHubReceiver> CreateReceiver(EventHubPartitionSettings partitionSettings, string offset, Logger logger, ITelemetryProducer telemetryProducer)
        {
            bool offsetInclusive         = true;
            var  connectionStringBuilder = new EventHubsConnectionStringBuilder(partitionSettings.Hub.ConnectionString)
            {
                EntityPath = partitionSettings.Hub.Path
            };
            EventHubClient client = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());

            // if we have a starting offset or if we're not configured to start reading from utc now, read from offset
            if (!partitionSettings.Hub.StartFromNow ||
                offset != EventHubConstants.StartOfStream)
            {
                logger.Info("Starting to read from EventHub partition {0}-{1} at offset {2}", partitionSettings.Hub.Path, partitionSettings.Partition, offset);
            }
            else
            {
                // to start reading from most recent data, we get the latest offset from the partition.
                EventHubPartitionRuntimeInformation partitionInfo =
                    await client.GetPartitionRuntimeInformationAsync(partitionSettings.Partition);

                offset          = partitionInfo.LastEnqueuedOffset;
                offsetInclusive = false;
                logger.Info("Starting to read latest messages from EventHub partition {0}-{1} at offset {2}", partitionSettings.Hub.Path, partitionSettings.Partition, offset);
            }

            PartitionReceiver receiver = client.CreateReceiver(partitionSettings.Hub.ConsumerGroup, partitionSettings.Partition, offset, offsetInclusive);

            if (partitionSettings.Hub.PrefetchCount.HasValue)
            {
                receiver.PrefetchCount = partitionSettings.Hub.PrefetchCount.Value;
            }

            return(new EventHubReceiverProxy(receiver));
        }
예제 #2
0
        /// <summary>
        ///   Retrieves information about a specific partition for an Event Hub, including elements that describe the available
        ///   events in the partition event stream.
        /// </summary>
        ///
        /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>The set of information for the requested partition under the Event Hub this client is associated with.</returns>
        ///
        public override async Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId,
                                                                                     CancellationToken cancellationToken)
        {
            try
            {
                EventHubPartitionRuntimeInformation runtimeInformation = await TrackOneClient.GetPartitionRuntimeInformationAsync(partitionId).ConfigureAwait(false);

                if (!long.TryParse(runtimeInformation.LastEnqueuedOffset, out var lastEnqueuedOffset))
                {
                    throw new FormatException(string.Format(CultureInfo.CurrentCulture, Resources.CannotParseIntegerType, nameof(runtimeInformation.LastEnqueuedOffset), 64, runtimeInformation.LastEnqueuedOffset));
                }

                return(new PartitionProperties
                       (
                           runtimeInformation.Path,
                           runtimeInformation.PartitionId,
                           runtimeInformation.BeginSequenceNumber,
                           runtimeInformation.LastEnqueuedSequenceNumber,
                           lastEnqueuedOffset,
                           runtimeInformation.LastEnqueuedTimeUtc,
                           runtimeInformation.IsEmpty
                       ));
            }
            catch (TrackOne.EventHubsException ex)
            {
                throw ex.MapToTrackTwoException();
            }
        }
예제 #3
0
        // Get the number of unprocessed events by deriving the delta between the server side info and the partition lease info,
        private long GetUnprocessedEventCount(EventHubPartitionRuntimeInformation partitionInfo, BlobPartitionLease 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);
        }
예제 #4
0
        private static async Task <EventHubReceiver> CreateReceiver(EventHubPartitionSettings partitionSettings, string offset, Logger logger)
#endif
        {
            bool offsetInclusive = true;

#if NETSTANDARD
            var connectionStringBuilder = new EventHubsConnectionStringBuilder(partitionSettings.Hub.ConnectionString)
            {
                EntityPath = partitionSettings.Hub.Path
            };
            EventHubClient client = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
#else
            EventHubClient client = EventHubClient.CreateFromConnectionString(partitionSettings.Hub.ConnectionString, partitionSettings.Hub.Path);

            EventHubConsumerGroup consumerGroup = client.GetConsumerGroup(partitionSettings.Hub.ConsumerGroup);
            if (partitionSettings.Hub.PrefetchCount.HasValue)
            {
                consumerGroup.PrefetchCount = partitionSettings.Hub.PrefetchCount.Value;
            }
#endif
            // if we have a starting offset or if we're not configured to start reading from utc now, read from offset
            if (!partitionSettings.Hub.StartFromNow ||
                offset != EventHubConstants.StartOfStream)
            {
                logger.Info("Starting to read from EventHub partition {0}-{1} at offset {2}", partitionSettings.Hub.Path, partitionSettings.Partition, offset);
            }
            else
            {
                // to start reading from most recent data, we get the latest offset from the partition.
#if NETSTANDARD
                EventHubPartitionRuntimeInformation partitionInfo =
#else
                PartitionRuntimeInformation partitionInfo =
#endif
                    await client.GetPartitionRuntimeInformationAsync(partitionSettings.Partition);

                offset          = partitionInfo.LastEnqueuedOffset;
                offsetInclusive = false;
                logger.Info("Starting to read latest messages from EventHub partition {0}-{1} at offset {2}", partitionSettings.Hub.Path, partitionSettings.Partition, offset);
            }
#if NETSTANDARD
            PartitionReceiver receiver = client.CreateReceiver(partitionSettings.Hub.ConsumerGroup, partitionSettings.Partition, offset, offsetInclusive);

            if (partitionSettings.Hub.PrefetchCount.HasValue)
            {
                receiver.PrefetchCount = partitionSettings.Hub.PrefetchCount.Value;
            }

            return(receiver);
#else
            return(await consumerGroup.CreateReceiverAsync(partitionSettings.Partition, offset, offsetInclusive));
#endif
        }
        private static async Task <IReadOnlyList <PartitionReceiver> > GetReceivers(EventHubClient eventHubClient, string consumerGroupName)
        {
            EventHubRuntimeInformation runtimeInformation = await eventHubClient.GetRuntimeInformationAsync();

            var receivers = new List <PartitionReceiver>();

            foreach (string partitionId in runtimeInformation.PartitionIds)
            {
                EventHubPartitionRuntimeInformation partitionRuntimeInformation =
                    await eventHubClient.GetPartitionRuntimeInformationAsync(partitionId);

                PartitionReceiver receiver = eventHubClient.CreateReceiver(
                    consumerGroupName,
                    partitionId,
                    partitionRuntimeInformation.LastEnqueuedOffset,
                    offsetInclusive: false);

                receivers.Add(receiver);
            }

            return(receivers);
        }
        async Task ValidateEnabledBehavior(PartitionReceiver partitionReceiver, EventHubPartitionRuntimeInformation pInfo)
        {
            Assert.True(partitionReceiver.ReceiverRuntimeMetricEnabled == true, "ReceiverRuntimeMetricEnabled == false");

            // Receive a message and validate RuntimeInfo is set.
            var messages = await partitionReceiver.ReceiveAsync(1);

            Assert.True(messages != null, "Failed to receive a message.");

            var message = messages.Single();

            Assert.True(partitionReceiver.RuntimeInfo.LastEnqueuedOffset == pInfo.LastEnqueuedOffset,
                        $"FAILED partitionReceiver.RuntimeInfo.LastEnqueuedOffset == {partitionReceiver.RuntimeInfo.LastEnqueuedOffset}");
            Assert.True(partitionReceiver.RuntimeInfo.LastEnqueuedTimeUtc == pInfo.LastEnqueuedTimeUtc,
                        $"FAILED partitionReceiver.RuntimeInfo.LastEnqueuedTimeUtc == {partitionReceiver.RuntimeInfo.LastEnqueuedTimeUtc}");
            Assert.True(partitionReceiver.RuntimeInfo.LastSequenceNumber == pInfo.LastEnqueuedSequenceNumber,
                        $"FAILED partitionReceiver.RuntimeInfo.LastSequenceNumber == {partitionReceiver.RuntimeInfo.LastSequenceNumber}");
            Assert.True(partitionReceiver.RuntimeInfo.RetrievalTime > DateTime.UtcNow.AddSeconds(-60),
                        $"FAILED partitionReceiver.RuntimeInfo.RetrievalTime == {partitionReceiver.RuntimeInfo.RetrievalTime}");
            Assert.True(partitionReceiver.RuntimeInfo.PartitionId == partitionReceiver.PartitionId,
                        $"FAILED partitionReceiver.RuntimeInfo.PartitionId == {partitionReceiver.RuntimeInfo.PartitionId}");
        }