public async Task ClientSettingInherited()
        {
            await using (var scope = await EventHubScope.CreateAsync(2))
            {
                var connectionString   = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient           = EventHubClient.CreateFromConnectionString(connectionString);
                var partitionReceiver1 = default(PartitionReceiver);
                var partitionReceiver2 = default(PartitionReceiver);

                try
                {
                    // Send some number of messages to target partition.
                    await TestUtility.SendToPartitionAsync(ehClient, targetPartitionId, "this is the message body", 10);

                    // Get partition runtime info so we can compare with runtime metrics.
                    var pInfo = await ehClient.GetPartitionRuntimeInformationAsync(targetPartitionId);

                    // Enable runtime metrics on the client.
                    ehClient.EnableReceiverRuntimeMetric = true;

                    // Create 2 new receivers. These receivers are expected to show runtime metrics since their parent client is enabled.
                    partitionReceiver1 =
                        ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, targetPartitionId, EventPosition.FromStart());
                    partitionReceiver2 =
                        ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, targetPartitionId, EventPosition.FromStart());

                    await ValidateEnabledBehavior(partitionReceiver1, pInfo);
                    await ValidateEnabledBehavior(partitionReceiver2, pInfo);
                }
                finally
                {
                    await Task.WhenAll(
                        partitionReceiver1?.CloseAsync(),
                        partitionReceiver2?.CloseAsync(),
                        ehClient.CloseAsync());
                }
            }
        }
        public async Task InvokeOnNull()
        {
            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString  = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient          = EventHubClient.CreateFromConnectionString(connectionString);
                var partitionReceiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromEnd());

                try
                {
                    var tcs     = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);
                    var handler = new TestPartitionReceiveHandler();

                    handler.EventsReceived += (s, eventDatas) =>
                    {
                        if (eventDatas == null)
                        {
                            TestUtility.Log("Received null.");
                            tcs.TrySetResult(true);
                        }
                    };

                    partitionReceiver.SetReceiveHandler(handler, true);
                    await tcs.Task.WithTimeout(TimeSpan.FromSeconds(120));
                }
                finally
                {
                    // Unregister handler.
                    partitionReceiver.SetReceiveHandler(null);

                    // Close clients.

                    await Task.WhenAll(
                        partitionReceiver.CloseAsync(),
                        ehClient.CloseAsync());
                }
            }
        }
Ejemplo n.º 3
0
        public async Task ChildEntityShouldInheritRetryPolicyFromParent()
        {
            var testMaxRetryCount = 99;

            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);
                ehClient.RetryPolicy = new RetryPolicyCustom(testMaxRetryCount);

                // Validate partition sender inherits.
                var sender = ehClient.CreateEventSender("0");
                Assert.True(sender.RetryPolicy is RetryPolicyCustom, "Sender failed to inherit parent client's RetryPolicy setting.");
                Assert.True((sender.RetryPolicy as RetryPolicyCustom).maximumRetryCount == testMaxRetryCount,
                            $"Retry policy on the sender shows testMaxRetryCount as {(sender.RetryPolicy as RetryPolicyCustom).maximumRetryCount}");

                // Validate partition receiver inherits.
                var receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromStart());
                Assert.True(receiver.RetryPolicy is RetryPolicyCustom, "Receiver failed to inherit parent client's RetryPolicy setting.");
                Assert.True((receiver.RetryPolicy as RetryPolicyCustom).maximumRetryCount == testMaxRetryCount,
                            $"Retry policy on the receiver shows testMaxRetryCount as {(receiver.RetryPolicy as RetryPolicyCustom).maximumRetryCount}");
            }
        }
Ejemplo n.º 4
0
        public async Task ProducerUpdatesPropertiesAfterPublishingBatches()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName);
                var options          = new IdempotentProducerOptions {
                    EnableIdempotentPartitions = true
                };

                await using var producer = new IdempotentProducer(connectionString, options);

                var cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit);

                var partition = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).First();
                var initialPartitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition);

                var batchOptions = new CreateBatchOptions {
                    PartitionId = partition
                };

                using var batch = await producer.CreateBatchAsync(batchOptions, cancellationSource.Token);

                batch.TryAdd(EventGenerator.CreateEvents(1).First());
                batch.TryAdd(EventGenerator.CreateEvents(1).First());
                batch.TryAdd(EventGenerator.CreateEvents(1).First());

                await producer.SendAsync(batch, cancellationSource.Token);

                var updatedPartitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition);

                Assert.That(updatedPartitionProperties.IsIdempotentPublishingEnabled, Is.True, "Idempotent publishing should be enabled.");
                Assert.That(updatedPartitionProperties.ProducerGroupId, Is.EqualTo(initialPartitionProperties.ProducerGroupId), "The producer group identifier should not have changed.");
                Assert.That(updatedPartitionProperties.OwnerLevel, Is.EqualTo(initialPartitionProperties.OwnerLevel), "The owner level should not have changed.");
                Assert.That(updatedPartitionProperties.LastPublishedSequenceNumber, Is.GreaterThan(initialPartitionProperties.LastPublishedSequenceNumber), "The last published sequence number should have increased.");
            }
        }
Ejemplo n.º 5
0
        public async Task CloseSenderClient()
        {
            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);
                var pSender          = ehClient.CreatePartitionSender("0");
                var pReceiver        = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromStart());

                try
                {
                    TestUtility.Log("Sending single event to partition 0");
                    using (var eventData = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!")))
                    {
                        await pSender.SendAsync(eventData);

                        TestUtility.Log("Closing partition sender");
                        await pSender.CloseAsync();
                    }

                    await Assert.ThrowsAsync <InvalidOperationException>(async() =>
                    {
                        TestUtility.Log("Sending another event to partition 0 on the closed sender, this should fail");
                        using (var eventData = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!")))
                        {
                            await pSender.SendAsync(eventData);
                        }
                    });
                }
                finally
                {
                    await Task.WhenAll(
                        pReceiver.CloseAsync(),
                        ehClient.CloseAsync());
                }
            }
        }
Ejemplo n.º 6
0
        public async Task Read()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            try
            {
                #region Snippet:EventHubs_ReadMe_Read

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

                string consumerGroup = EventHubConsumerClient.DefaultConsumerGroupName;

                await using (var consumer = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName))
                {
                    using var cancellationSource = new CancellationTokenSource();
                    cancellationSource.CancelAfter(TimeSpan.FromSeconds(45));

                    await foreach (PartitionEvent receivedEvent in consumer.ReadEventsAsync(cancellationSource.Token))
                    {
                        // At this point, the loop will wait for events to be available in the Event Hub.  When an event
                        // is available, the loop will iterate with the event that was received.  Because we did not
                        // specify a maximum wait time, the loop will wait forever unless cancellation is requested using
                        // the cancellation token.
                    }
                }

                #endregion
            }
            catch (TaskCanceledException)
            {
                // Expected
            }
        }
Ejemplo n.º 7
0
        public async Task SmallReceiveTimeout()
        {
            var maxClients = 4;

            // Issue receives with 1 second so that some of the Receive calls will timeout while creating AMQP link.
            // Even those Receive calls should return NULL instead of bubbling the exception up.
            var receiveTimeoutInSeconds = 1;

            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var tasks = Enumerable.Range(0, maxClients)
                            .Select(async i =>
                {
                    PartitionReceiver receiver = null;

                    try
                    {
                        TestUtility.Log($"Testing with {receiveTimeoutInSeconds} seconds on client {i}.");
                        // Start receiving from a future time so that Receive call won't be able to fetch any events.
                        var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                        var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);
                        receiver             = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "0", EventPosition.FromEnqueuedTime(DateTime.UtcNow.AddMinutes(1)));
                        var ed = await receiver.ReceiveAsync(1, TimeSpan.FromSeconds(receiveTimeoutInSeconds));
                        if (ed == null)
                        {
                            TestUtility.Log($"Received NULL from client {i}");
                        }
                    }
                    finally
                    {
                        await receiver.CloseAsync();
                    }
                });

                await Task.WhenAll(tasks);
            }
        }
        public async Task ConfigureConsumerRetryWithFullOptions()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample02_ConsumerRetryWithFullOptions

            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 consumerOptions = new EventHubConsumerClientOptions
            {
                RetryOptions = new EventHubsRetryOptions
                {
                    Mode           = EventHubsRetryMode.Exponential,
                    MaximumRetries = 5,
                    Delay          = TimeSpan.FromMilliseconds(800),
                    MaximumDelay   = TimeSpan.FromSeconds(10)
                }
            };

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

            #endregion

            using var cancellationSource = new CancellationTokenSource();
            cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit);

            await consumer.CloseAsync(cancellationSource.Token).IgnoreExceptions();
        }
        public async Task InspectPartition()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #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
        }
Ejemplo n.º 10
0
        public async Task NoBatch()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample04_NoBatch

#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 producer = new EventHubProducerClient(connectionString, eventHubName);

            try
            {
                var eventsToSend = new List <EventData>();

                for (var index = 0; index < 10; ++index)
                {
                    var eventBody = new BinaryData("Hello, Event Hubs!");
                    var eventData = new EventData(eventBody);

                    eventsToSend.Add(eventData);
                }

                await producer.SendAsync(eventsToSend);
            }
            finally
            {
                await producer.CloseAsync();
            }

            #endregion
        }
Ejemplo n.º 11
0
        public async Task CreateNonEpochReceiverAfterEpochReceiver()
        {
            await using (var scope = await EventHubScope.CreateAsync(2))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);
                var epochReceiver    = ehClient.CreateEpochReceiver(PartitionReceiver.DefaultConsumerGroupName, "1", EventPosition.FromStart(), 1);
                var nonEpochReceiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, "1", EventPosition.FromStart());

                try
                {
                    TestUtility.Log("Starting epoch receiver");
                    await epochReceiver.ReceiveAsync(10);

                    await Task.Delay(TimeSpan.FromSeconds(10));

                    try
                    {
                        TestUtility.Log("Starting nonepoch receiver, this should fail");
                        await nonEpochReceiver.ReceiveAsync(10);

                        throw new InvalidOperationException("Non-Epoch receiver should have encountered an exception by now!");
                    }
                    catch (ReceiverDisconnectedException ex) when(ex.Message.Contains("non-epoch receiver is not allowed"))
                    {
                        TestUtility.Log($"Received expected exception {ex.GetType()}: {ex.Message}");
                    }
                }
                finally
                {
                    await Task.WhenAll(
                        epochReceiver.CloseAsync(),
                        nonEpochReceiver.CloseAsync(),
                        ehClient.CloseAsync());
                }
            }
        }
Ejemplo n.º 12
0
        public async Task ProducerInitializesPropertiesWhenRequested()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(2))
            {
                var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName);
                var options          = new IdempotentProducerOptions {
                    EnableIdempotentPartitions = true
                };

                await using var producer = new IdempotentProducer(connectionString, options);

                var cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit);

                var partition           = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).Last();
                var partitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition);

                Assert.That(partitionProperties, Is.Not.Null, "The properties should have been created.");
                Assert.That(partitionProperties.IsIdempotentPublishingEnabled, Is.True, "Idempotent publishing should be enabled.");
                Assert.That(partitionProperties.ProducerGroupId.HasValue, Is.True, "The producer group identifier should have a value.");
                Assert.That(partitionProperties.OwnerLevel.HasValue, Is.True, "The owner level should have a value.");
                Assert.That(partitionProperties.LastPublishedSequenceNumber.HasValue, Is.True, "The last published sequence number should have a value.");
            }
        }
Ejemplo n.º 13
0
        public async Task SendBatch()
        {
            TestUtility.Log("Sending multiple Events via EventHubClient.SendAsync(IEnumerable<EventData>)");

            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);

                try
                {
                    using (var eventData1 = new EventData(Encoding.UTF8.GetBytes("Hello EventHub!")))
                        using (var eventData2 = new EventData(Encoding.UTF8.GetBytes("This is another message in the batch!")))
                        {
                            eventData2.Properties["ContosoEventType"] = "some value here";
                            await ehClient.SendAsync(new[] { eventData1, eventData2 });
                        }
                }
                finally
                {
                    await ehClient.CloseAsync();
                }
            }
        }
Ejemplo n.º 14
0
        public async Task Publish()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample07_Publish

#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 producer = new EventHubProducerClient(connectionString, eventHubName);

            try
            {
                using (var eventBatch = await producer.CreateBatchAsync())
                {
                    var eventBody = new BinaryData("This is an event body");
                    var eventData = new EventData(eventBody);

                    if (!eventBatch.TryAdd(eventData))
                    {
                        throw new Exception($"The event could not be added.");
                    }
                }
            }
            finally
            {
                await producer.CloseAsync();
            }

            #endregion
        }
Ejemplo n.º 15
0
        public async Task Publish()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_ReadMe_Publish

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

            await using (var producer = new EventHubProducerClient(connectionString, eventHubName))
            {
                using EventDataBatch eventBatch = await producer.CreateBatchAsync();

                eventBatch.TryAdd(new EventData(new BinaryData("First")));
                eventBatch.TryAdd(new EventData(new BinaryData("Second")));

                await producer.SendAsync(eventBatch);
            }

            #endregion
        }
        /// <summary>
        ///   Performs the tasks needed to initialize and set up the environment for the test scenario.
        ///   When multiple instances are run in parallel, the setup will take place once, prior to the
        ///   execution of the first test instance.
        /// </summary>
        ///
        public async override Task GlobalSetupAsync()
        {
            await base.GlobalSetupAsync().ConfigureAwait(false);

            s_scope = await EventHubScope.CreateAsync(4).ConfigureAwait(false);

            s_client    = EventHubClient.CreateFromConnectionString(TestUtility.BuildEventHubsConnectionString(s_scope.EventHubName));
            s_eventBody = EventGenerator.CreateRandomBody(Options.Size);

            var partition = (await s_client.GetRuntimeInformationAsync().ConfigureAwait(false)).PartitionIds[0];

            s_sender = s_client.CreatePartitionSender(partition);

            // Publish an empty event to force the connection and link to be established.

            using var batch = s_sender.CreateBatch();

            if (!batch.TryAdd(new EventData(Array.Empty <byte>())))
            {
                throw new InvalidOperationException("The empty event could not be added to the batch during global setup.");
            }

            await s_sender.SendAsync(batch).ConfigureAwait(false);
        }
        public async Task ProducerSequencesEvents()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(2))
            {
                var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName);
                var options          = new EventHubProducerClientOptions {
                    EnableIdempotentPartitions = true
                };

                await using var producer = new EventHubProducerClient(connectionString, options);

                var cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit);

                var partition   = (await producer.GetPartitionIdsAsync(cancellationSource.Token)).Last();
                var sendOptions = new SendEventOptions {
                    PartitionId = partition
                };

                var partitionProperties = await producer.GetPartitionPublishingPropertiesAsync(partition);

                var eventSequenceNumber = partitionProperties.LastPublishedSequenceNumber;

                var events = EventGenerator.CreateEvents(10).ToArray();
                Assert.That(events.Any(item => item.PublishedSequenceNumber.HasValue), Is.False, "Events should start out as unpublished with no sequence number.");

                await producer.SendAsync(events, sendOptions, cancellationSource.Token);

                Assert.That(events.All(item => item.PublishedSequenceNumber.HasValue), Is.True, "Events should be sequenced after publishing.");

                foreach (var item in events)
                {
                    Assert.That(item.PublishedSequenceNumber, Is.EqualTo(++eventSequenceNumber), $"The sequence numbers should be contiguous.  Event { eventSequenceNumber } was out of order.");
                }
            }
        }
        public async Task ProcessByBatch()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample04_ProcessByBatch

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            const int EventsInBatch         = 50;
            var       partitionEventBatches = new ConcurrentDictionary <string, List <EventData> >();
            var       checkpointNeeded      = false;

            async Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    string partition = args.Partition.PartitionId;

                    List <EventData> partitionBatch =
                        partitionEventBatches.GetOrAdd(
                            partition,
                            new List <EventData>());

                    partitionBatch.Add(args.Data);

                    if (partitionBatch.Count >= EventsInBatch)
                    {
                        await Application.ProcessEventBatchAsync(
                            partitionBatch,
                            args.Partition,
                            args.CancellationToken);

                        checkpointNeeded = true;
                        partitionBatch.Clear();
                    }

                    if (checkpointNeeded)
                    {
                        await args.UpdateCheckpointAsync();

                        checkpointNeeded = false;
                    }
                }
                catch (Exception ex)
                {
                    Application.HandleProcessingException(args, ex);
                }
            }

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

                // The error handler is not relevant for this sample; for
                // illustration, it is delegating the implementation to the
                // host application.

                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += Application.ProcessorErrorHandler;

                try
                {
                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            catch
            {
                // If this block is invoked, then something external to the
                // processor was the source of the exception.
            }
            finally
            {
                // It is encouraged that you unregister your handlers when you have
                // finished using the Event Processor to ensure proper cleanup.

                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= Application.ProcessorErrorHandler;
            }

            #endregion
        }
        public async Task ProcessWithHeartbeat()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample04_ProcessWithHeartbeat

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processorOptions = new EventProcessorClientOptions
            {
                MaximumWaitTime = TimeSpan.FromMilliseconds(250)
            };

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName,
                processorOptions);

            async Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    if (args.HasEvent)
                    {
                        await Application.ProcessEventAndCheckpointAsync(
                            args.Data,
                            args.Partition,
                            args.CancellationToken);
                    }

                    await Application.SendHeartbeatAsync(args.CancellationToken);
                }
                catch (Exception ex)
                {
                    Application.HandleProcessingException(args, ex);
                }
            }

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

                // The error handler is not relevant for this sample; for
                // illustration, it is delegating the implementation to the
                // host application.

                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += Application.ProcessorErrorHandler;

                try
                {
                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take slightly longer than the length of
                    // time defined as part of the MaximumWaitTime configured
                    // for the processor; in this example, 250 milliseconds.

                    await processor.StopProcessingAsync();
                }
            }
            catch
            {
                // If this block is invoked, then something external to the
                // processor was the source of the exception.
            }
            finally
            {
                // It is encouraged that you unregister your handlers when you have
                // finished using the Event Processor to ensure proper cleanup.

                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= Application.ProcessorErrorHandler;
            }

            #endregion
        }
        public async Task InitializePartition()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample04_InitializePartition

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            Task initializeEventHandler(PartitionInitializingEventArgs args)
            {
                try
                {
                    if (args.CancellationToken.IsCancellationRequested)
                    {
                        return(Task.CompletedTask);
                    }

                    // If no checkpoint was found, start processing
                    // events enqueued now or in the future.

                    EventPosition startPositionWhenNoCheckpoint =
                        EventPosition.FromEnqueuedTime(DateTimeOffset.UtcNow);

                    args.DefaultStartingPosition = startPositionWhenNoCheckpoint;
                }
                catch (Exception ex)
                {
                    Application.HandleInitializeException(args, ex);
                }

                return(Task.CompletedTask);
            }

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

                // The event handlers for processing events and errors are
                // not relevant for this sample; for illustration, they're
                // delegating the implementation to the host application.

                processor.PartitionInitializingAsync += initializeEventHandler;
                processor.ProcessEventAsync          += Application.ProcessorEventHandler;
                processor.ProcessErrorAsync          += Application.ProcessorErrorHandler;

                try
                {
                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            catch
            {
                // If this block is invoked, then something external to the
                // processor was the source of the exception.
            }
            finally
            {
                // It is encouraged that you unregister your handlers when you have
                // finished using the Event Processor to ensure proper cleanup

                processor.PartitionInitializingAsync -= initializeEventHandler;
                processor.ProcessEventAsync          -= Application.ProcessorEventHandler;
                processor.ProcessErrorAsync          -= Application.ProcessorErrorHandler;
            }

            #endregion
        }
        public async Task BasicEventProcessing()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample04_BasicEventProcessing

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    if (args.CancellationToken.IsCancellationRequested)
                    {
                        return(Task.CompletedTask);
                    }

                    string partition = args.Partition.PartitionId;
                    byte[] eventBody = args.Data.EventBody.ToArray();
                    Debug.WriteLine($"Event from partition { partition } with length { eventBody.Length }.");
                }
                catch
                {
                    // It is very important that you always guard against
                    // exceptions in your handler code; the processor does
                    // not have enough understanding of your code to
                    // determine the correct action to take.  Any
                    // exceptions from your handlers go uncaught by
                    // the processor and will NOT be redirected to
                    // the error handler.
                }

                return(Task.CompletedTask);
            }

            Task processErrorHandler(ProcessErrorEventArgs args)
            {
                try
                {
                    Debug.WriteLine("Error in the EventProcessorClient");
                    Debug.WriteLine($"\tOperation: { args.Operation }");
                    Debug.WriteLine($"\tException: { args.Exception }");
                    Debug.WriteLine("");
                }
                catch (Exception ex)
                {
                    // It is very important that you always guard against
                    // exceptions in your handler code; the processor does
                    // not have enough understanding of your code to
                    // determine the correct action to take.  Any
                    // exceptions from your handlers go uncaught by
                    // the processor and will NOT be handled in any
                    // way.

                    Application.HandleErrorException(args, ex);
                }

                return(Task.CompletedTask);
            }

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

                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += processErrorHandler;

                try
                {
                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            catch
            {
                // The processor will automatically attempt to recover from any
                // failures, either transient or fatal, and continue processing.
                // Errors in the processor's operation will be surfaced through
                // its error handler.
                //
                // If this block is invoked, then something external to the
                // processor was the source of the exception.
            }
            finally
            {
                // It is encouraged that you unregister your handlers when you have
                // finished using the Event Processor to ensure proper cleanup.  This
                // is especially important when using lambda expressions or handlers
                // in any form that may contain closure scopes or hold other references.

                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= processErrorHandler;
            }

            #endregion
        }
        public async Task CustomMetadata()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample04_CustomMetadata

#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 producer = new EventHubBufferedProducerClient(connectionString, eventHubName);

            // The failure handler is required and invoked after all allowable
            // retries were applied.

            producer.SendEventBatchFailedAsync += args =>
            {
                Debug.WriteLine($"Publishing failed for { args.EventBatch.Count } events.  Error: '{ args.Exception.Message }'");
                return(Task.CompletedTask);
            };

            // The success handler is optional.

            producer.SendEventBatchSucceededAsync += args =>
            {
                Debug.WriteLine($"{ args.EventBatch.Count } events were published to partition: '{ args.PartitionId }.");
                return(Task.CompletedTask);
            };

            try
            {
                var eventData = new EventData("Hello, Event Hubs!")
                {
                    MessageId   = "H1",
                    ContentType = "application/json"
                };

                eventData.Properties.Add("EventType", "com.microsoft.samples.hello-event");
                eventData.Properties.Add("priority", 1);
                eventData.Properties.Add("score", 9.0);

                await producer.EnqueueEventAsync(eventData);

                eventData = new EventData("Goodbye, Event Hubs!")
                {
                    MessageId   = "G1",
                    ContentType = "application/json"
                };

                eventData.Properties.Add("EventType", "com.microsoft.samples.goodbye-event");
                eventData.Properties.Add("priority", "17");
                eventData.Properties.Add("blob", true);

                await producer.EnqueueEventAsync(eventData);
            }
            finally
            {
                // Closing the producer will flush any
                // enqueued events that have not been published.

                await producer.CloseAsync();
            }

            #endregion
        }
        public async Task CheckpointByEventCount()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample04_CheckpointByEventCount

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            const int EventsBeforeCheckpoint = 25;
            var       partitionEventCount    = new ConcurrentDictionary <string, int>();

            async Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    await Application.ProcessEventAsync(
                        args.Data,
                        args.Partition,
                        args.CancellationToken);

                    // If the number of events that have been processed
                    // since the last checkpoint was created exceeds the
                    // checkpointing threshold, a new checkpoint will be
                    // created and the count reset.

                    string partition = args.Partition.PartitionId;

                    int eventsSinceLastCheckpoint = partitionEventCount.AddOrUpdate(
                        key: partition,
                        addValue: 1,
                        updateValueFactory: (_, currentCount) => currentCount + 1);

                    if (eventsSinceLastCheckpoint >= EventsBeforeCheckpoint)
                    {
                        await args.UpdateCheckpointAsync();

                        partitionEventCount[partition] = 0;
                    }
                }
                catch (Exception ex)
                {
                    Application.HandleProcessingException(args, ex);
                }
            }

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

                // The error handler is not relevant for this sample; for
                // illustration, it is delegating the implementation to the
                // host application.

                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += Application.ProcessorErrorHandler;

                try
                {
                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            catch
            {
                // If this block is invoked, then something external to the
                // processor was the source of the exception.
            }
            finally
            {
                // It is encouraged that you unregister your handlers when you have
                // finished using the Event Processor to ensure proper cleanup

                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= Application.ProcessorErrorHandler;
            }

            #endregion
        }
        public async Task FixtureSetUp()
        {
            _eventHubScope = await EventHubScope.CreateAsync(2);

            _storageScope = await StorageScope.CreateAsync();
        }
Ejemplo n.º 25
0
        public async Task ReadAllPartitions()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample07_ReadAllPartitions

            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
            {
                using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
                {
                    cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));

                    int eventsRead    = 0;
                    int maximumEvents = 50;

                    IAsyncEnumerator <PartitionEvent> iterator =
                        consumer.ReadEventsAsync(cancellationSource.Token).GetAsyncEnumerator();

                    try
                    {
                        while (await iterator.MoveNextAsync())
                        {
                            PartitionEvent partitionEvent    = iterator.Current;
                            string         readFromPartition = partitionEvent.Partition.PartitionId;
                            byte[]         eventBodyBytes    = partitionEvent.Data.EventBody.ToArray();

                            Debug.WriteLine($"Read event of length { eventBodyBytes.Length } from { readFromPartition }");
                            eventsRead++;

                            if (eventsRead >= maximumEvents)
                            {
                                break;
                            }
                        }
                    }
                    catch (TaskCanceledException)
                    {
                        // This is expected if the cancellation token is
                        // signaled.
                    }
                    finally
                    {
                        await iterator.DisposeAsync();
                    }
                }
            }
            finally
            {
                await consumer.CloseAsync();
            }

            #endregion
        }
Ejemplo n.º 26
0
        public async Task ErrorHandlerCancellationRecovery()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample03_ErrorHandlerCancellationRecovery

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            // This token is used to control processing,
            // if signaled, then processing will be stopped.

            using var cancellationSource = new CancellationTokenSource();
#if !SNIPPET
            cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));
#endif

            Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    // Process the event.
                }
                catch
                {
                    // Handle the exception.
                }

                return(Task.CompletedTask);
            }

            async Task processErrorHandler(ProcessErrorEventArgs args)
            {
                try
                {
                    // Always log the exception.

                    Debug.WriteLine("Error in the EventProcessorClient");
                    Debug.WriteLine($"\tOperation: { args.Operation ?? "Unknown" }");
                    Debug.WriteLine($"\tPartition: { args.PartitionId ?? "None" }");
                    Debug.WriteLine($"\tException: { args.Exception }");
                    Debug.WriteLine("");

                    // If cancellation was requested, assume that
                    // it was in response to an application request
                    // and take no action.

                    if (args.CancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    // If out of memory, signal for cancellation.

                    if (args.Exception is OutOfMemoryException)
                    {
                        cancellationSource.Cancel();
                        return;
                    }

                    // If processing stopped and this handler determined
                    // the error to be non-fatal, restart processing.

                    if ((!processor.IsRunning) &&
                        (!cancellationSource.IsCancellationRequested))
                    {
                        // To be safe, request that processing stop before
                        // requesting the start; this will ensure that any
                        // processor state is fully reset.

                        await processor.StopProcessingAsync();

                        await processor.StartProcessingAsync(cancellationSource.Token);
                    }
                }
                catch
                {
                    // Handle the exception.  If fatal, signal
                    // for cancellation.
                }
            }

            try
            {
                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += processErrorHandler;

                try
                {
                    // Once processing has started, the delay will
                    // block to allow processing until cancellation
                    // is requested.

                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            finally
            {
                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= processErrorHandler;
            }

            #endregion
        }
Ejemplo n.º 27
0
        public async Task EventHandlerStopOnException()
        {
            await using var eventHubScope = await EventHubScope.CreateAsync(1);

            await using var storageScope = await StorageScope.CreateAsync();

            #region Snippet:EventHubs_Processor_Sample03_EventHandlerStopOnException

#if SNIPPET
            var storageConnectionString = "<< CONNECTION STRING FOR THE STORAGE ACCOUNT >>";
            var blobContainerName       = "<< NAME OF THE BLOB CONTAINER >>";

            var eventHubsConnectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
            var eventHubName  = "<< NAME OF THE EVENT HUB >>";
            var consumerGroup = "<< NAME OF THE EVENT HUB CONSUMER GROUP >>";
#else
            var storageConnectionString   = StorageTestEnvironment.Instance.StorageConnectionString;
            var blobContainerName         = storageScope.ContainerName;
            var eventHubsConnectionString = EventHubsTestEnvironment.Instance.EventHubsConnectionString;
            var eventHubName  = eventHubScope.EventHubName;
            var consumerGroup = eventHubScope.ConsumerGroups.First();
#endif

            var storageClient = new BlobContainerClient(
                storageConnectionString,
                blobContainerName);

            var processor = new EventProcessorClient(
                storageClient,
                consumerGroup,
                eventHubsConnectionString,
                eventHubName);

            // This token is used to control processing,
            // if signaled, then processing will be stopped.

            using var cancellationSource = new CancellationTokenSource();
#if !SNIPPET
            cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));
#endif

            Task processEventHandler(ProcessEventArgs args)
            {
                try
                {
                    if (args.CancellationToken.IsCancellationRequested)
                    {
                        return(Task.CompletedTask);
                    }

                    // Process the event.
                }
                catch
                {
                    // Handle the exception.  If fatal,
                    // signal for cancellation.

                    cancellationSource.Cancel();
                }

                return(Task.CompletedTask);
            }

            Task processErrorHandler(ProcessErrorEventArgs args)
            {
                // Process the error, as appropriate for the
                // application.

                return(Task.CompletedTask);
            }

            try
            {
                processor.ProcessEventAsync += processEventHandler;
                processor.ProcessErrorAsync += processErrorHandler;

                try
                {
                    // Once processing has started, the delay will
                    // block to allow processing until cancellation
                    // is requested.

                    await processor.StartProcessingAsync(cancellationSource.Token);

                    await Task.Delay(Timeout.Infinite, cancellationSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // This is expected if the cancellation token is
                    // signaled.
                }
                finally
                {
                    // This may take up to the length of time defined
                    // as part of the configured TryTimeout of the processor;
                    // by default, this is 60 seconds.

                    await processor.StopProcessingAsync();
                }
            }
            finally
            {
                processor.ProcessEventAsync -= processEventHandler;
                processor.ProcessErrorAsync -= processErrorHandler;
            }

            #endregion
        }
Ejemplo n.º 28
0
        public async Task ReadPartitionWaitTime()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample05_ReadPartitionWaitTime

            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
            {
                using CancellationTokenSource cancellationSource = new CancellationTokenSource();
                cancellationSource.CancelAfter(TimeSpan.FromSeconds(30));

                string        firstPartition   = (await consumer.GetPartitionIdsAsync(cancellationSource.Token)).First();
                EventPosition startingPosition = EventPosition.Earliest;

                int loopTicks    = 0;
                int maximumTicks = 10;

                var options = new ReadEventOptions
                {
                    MaximumWaitTime = TimeSpan.FromSeconds(1)
                };

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

                        Debug.WriteLine($"Read event of length { eventBodyBytes.Length } from { readFromPartition }");
                    }
                    else
                    {
                        Debug.WriteLine("Wait time elapsed; no event was available.");
                    }

                    loopTicks++;

                    if (loopTicks >= maximumTicks)
                    {
                        break;
                    }
                }
            }
            catch (TaskCanceledException)
            {
                // This is expected if the cancellation token is
                // signaled.
            }
            finally
            {
                await consumer.CloseAsync();
            }

            #endregion
        }
Ejemplo n.º 29
0
        public async Task CreateReceiverWithEndOfStream()
        {
            var receiver        = default(PartitionReceiver);
            var partitionSender = default(PartitionSender);

            await using (var scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestUtility.BuildEventHubsConnectionString(scope.EventHubName);
                var ehClient         = EventHubClient.CreateFromConnectionString(connectionString);

                try
                {
                    // Randomly pick one of the available partitons.
                    var partitions = await this.GetPartitionsAsync(ehClient);

                    var partitionId = partitions[new Random().Next(partitions.Length)];
                    TestUtility.Log($"Randomly picked partition {partitionId}");

                    partitionSender = ehClient.CreatePartitionSender(partitionId);

                    // Send couple of messages before creating an EndOfStream receiver.
                    // We are not expecting to receive these messages would be sent before receiver creation.
                    for (int i = 0; i < 10; i++)
                    {
                        var ed = new EventData(new byte[1]);
                        await partitionSender.SendAsync(ed);
                    }

                    // Create a new receiver which will start reading from the end of the stream.
                    TestUtility.Log($"Creating a new receiver with offset EndOFStream");
                    receiver = ehClient.CreateReceiver(PartitionReceiver.DefaultConsumerGroupName, partitionId, EventPosition.FromEnd());

                    // Attemp to receive the message. This should return only 1 message.
                    var receiveTask = receiver.ReceiveAsync(100);

                    // Send a new message which is expected to go to the end of stream.
                    // We are expecting to receive only this message.
                    // Wait 5 seconds before sending to avoid race.
                    await Task.Delay(5000);

                    var eventToReceive = new EventData(new byte[1]);
                    eventToReceive.Properties["stamp"] = Guid.NewGuid().ToString();
                    await partitionSender.SendAsync(eventToReceive);

                    // Complete asyncy receive task.
                    var receivedMessages = await receiveTask;

                    // We should have received only 1 message from this call.
                    Assert.True(receivedMessages.Count() == 1, $"Didn't receive 1 message. Received {receivedMessages.Count()} messages(s).");

                    // Check stamp.
                    Assert.True(receivedMessages.Single().Properties["stamp"].ToString() == eventToReceive.Properties["stamp"].ToString()
                                , "Stamps didn't match on the message sent and received!");

                    TestUtility.Log("Received correct message as expected.");

                    // Next receive on this partition shouldn't return any more messages.
                    receivedMessages = await receiver.ReceiveAsync(100, TimeSpan.FromSeconds(15));

                    Assert.True(receivedMessages == null, $"Received messages at the end.");
                }
                finally
                {
                    await Task.WhenAll(
                        partitionSender.CloseAsync(),
                        receiver.CloseAsync(),
                        ehClient.CloseAsync());
                }
            }
        }
Ejemplo n.º 30
0
        public async Task ReadPartitionWithReceiver()
        {
            await using var scope = await EventHubScope.CreateAsync(1);

            #region Snippet:EventHubs_Sample05_ReadPartitionWithReceiver

            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;

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

            string firstPartition;

            await using (var producer = new EventHubProducerClient(connectionString, eventHubName))
            {
                firstPartition = (await producer.GetPartitionIdsAsync()).First();
            }

            var receiver = new PartitionReceiver(
                consumerGroup,
                firstPartition,
                EventPosition.Earliest,
                connectionString,
                eventHubName);

            try
            {
                while (!cancellationSource.IsCancellationRequested)
                {
                    int      batchSize = 50;
                    TimeSpan waitTime  = TimeSpan.FromSeconds(1);

                    IEnumerable <EventData> eventBatch = await receiver.ReceiveBatchAsync(
                        batchSize,
                        waitTime,
                        cancellationSource.Token);

                    foreach (EventData eventData in eventBatch)
                    {
                        byte[] eventBodyBytes = eventData.EventBody.ToArray();
                        Debug.WriteLine($"Read event of length { eventBodyBytes.Length } from { firstPartition }");
                    }
                }
            }
            catch (TaskCanceledException)
            {
                // This is expected if the cancellation token is
                // signaled.
            }
            finally
            {
                await receiver.CloseAsync();
            }

            #endregion
        }