public async Task OwnershipClaimDoesNotInterfereWithOtherNamespaces()
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownershipList    = new List <PartitionOwnership>();
            var firstOwnership   =
                new PartitionOwnership
                (
                    "namespace1",
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId"
                );

            ownershipList.Add(firstOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            // ETag must have been set by the partition manager.

            var eTag = firstOwnership.ETag;

            ownershipList.Clear();

            var secondOwnership =
                new PartitionOwnership
                (
                    "namespace2",
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId",
                    eTag: eTag
                );

            ownershipList.Add(secondOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            IEnumerable <PartitionOwnership> storedOwnership1 = await partitionManager.ListOwnershipAsync("namespace1", "eventHubName", "consumerGroup");

            IEnumerable <PartitionOwnership> storedOwnership2 = await partitionManager.ListOwnershipAsync("namespace2", "eventHubName", "consumerGroup");

            Assert.That(storedOwnership1, Is.Not.Null);
            Assert.That(storedOwnership1.Count, Is.EqualTo(1));
            Assert.That(storedOwnership1.Single(), Is.EqualTo(firstOwnership));

            Assert.That(storedOwnership2, Is.Not.Null);
            Assert.That(storedOwnership2.Count, Is.EqualTo(1));
            Assert.That(storedOwnership2.Single(), Is.EqualTo(secondOwnership));
        }
        public async Task ListOwnershipAsyncReturnsEmptyIEnumerableWhenThereAreNoOwnership()
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownership        = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(ownership, Is.Not.Null.And.Empty);
        }
        public async Task ClaimOwnershipAsyncCanClaimMultipleOwnership()
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownershipList    = new List <PartitionOwnership>();
            var ownershipCount   = 5;

            for (int i = 0; i < ownershipCount; i++)
            {
                ownershipList.Add(
                    new PartitionOwnership
                    (
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        $"partitionId { i }"
                    ));
            }

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(ownershipCount));
            Assert.That(storedOwnership.OrderBy(ownership => ownership.PartitionId).SequenceEqual(ownershipList), Is.True);
        }
        public async Task CheckpointUpdateUpdatesOwnershipInformation()
        {
            var partitionManager  = new InMemoryPartitionManager();
            var originalOwnership = new PartitionOwnership
                                        ("eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", offset: 1, sequenceNumber: 2, lastModifiedTime: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1)));

            await partitionManager.ClaimOwnershipAsync(new List <PartitionOwnership>()
            {
                originalOwnership
            });

            // ETag must have been set by the partition manager.

            var originalLastModifiedTime = originalOwnership.LastModifiedTime;
            var originalETag             = originalOwnership.ETag;

            await partitionManager.UpdateCheckpointAsync(new Checkpoint
                                                         ("eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", 10, 20));

            // Make sure the ownership has changed, even though the instance should be the same.

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(1));
            Assert.That(storedOwnership.Single(), Is.EqualTo(originalOwnership));

            Assert.That(originalOwnership.Offset, Is.EqualTo(10));
            Assert.That(originalOwnership.SequenceNumber, Is.EqualTo(20));
            Assert.That(originalOwnership.LastModifiedTime, Is.GreaterThan(originalLastModifiedTime));
            Assert.That(originalOwnership.ETag, Is.Not.EqualTo(originalETag));
        }
        public async Task CheckpointUpdateFailsWhenOwnerChanges()
        {
            var partitionManager  = new InMemoryPartitionManager();
            var originalOwnership = new PartitionOwnership
                                        ("eventHubName", "consumerGroup", "ownerIdentifier1", "partitionId", offset: 1, sequenceNumber: 2, lastModifiedTime: DateTimeOffset.UtcNow);

            await partitionManager.ClaimOwnershipAsync(new List <PartitionOwnership>()
            {
                originalOwnership
            });

            // ETag must have been set by the partition manager.

            var originalLastModifiedTime = originalOwnership.LastModifiedTime;
            var originalETag             = originalOwnership.ETag;

            await partitionManager.UpdateCheckpointAsync(new Checkpoint
                                                         ("eventHubName", "consumerGroup", "ownerIdentifier2", "partitionId", 10, 20));

            // Make sure the ownership hasn't changed.

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(1));
            Assert.That(storedOwnership.Single(), Is.EqualTo(originalOwnership));

            Assert.That(originalOwnership.OwnerIdentifier, Is.EqualTo("ownerIdentifier1"));
            Assert.That(originalOwnership.Offset, Is.EqualTo(1));
            Assert.That(originalOwnership.SequenceNumber, Is.EqualTo(2));
            Assert.That(originalOwnership.LastModifiedTime, Is.EqualTo(originalLastModifiedTime));
            Assert.That(originalOwnership.ETag, Is.EqualTo(originalETag));
        }
        public async Task CheckpointUpdateFailsWhenAssociatedOwnershipDoesNotExist()
        {
            var partitionManager = new InMemoryPartitionManager();

            await partitionManager.UpdateCheckpointAsync(new Checkpoint
                                                         ("eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", offset : 10, sequenceNumber : 20));

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership, Is.Empty);
        }
        public async Task OwnershipClaimSucceedsWhenETagIsValid()
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownershipList    = new List <PartitionOwnership>();
            var firstOwnership   =
                new PartitionOwnership
                (
                    "namespace",
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId",
                    offset: 1
                );

            ownershipList.Add(firstOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            // ETag must have been set by the partition manager.

            var eTag = firstOwnership.ETag;

            ownershipList.Clear();

            var secondOwnership =
                new PartitionOwnership
                (
                    "namespace",
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId",
                    offset: 2,
                    eTag: eTag
                );

            ownershipList.Add(secondOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            IEnumerable <PartitionOwnership> storedOwnership = await partitionManager.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(1));
            Assert.That(storedOwnership.Single(), Is.EqualTo(secondOwnership));
        }
        public async Task OwnershipClaimFailsWhenETagIsInvalid(string eTag)
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownershipList    = new List <PartitionOwnership>();
            var firstOwnership   =
                new PartitionOwnership
                (
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId",
                    offset: 1
                );

            ownershipList.Add(firstOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            ownershipList.Clear();

            var secondOwnership =
                new PartitionOwnership
                (
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId",
                    offset: 2,
                    eTag: eTag
                );

            ownershipList.Add(secondOwnership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(1));
            Assert.That(storedOwnership.Single(), Is.EqualTo(firstOwnership));
        }
        public async Task FirstOwnershipClaimSucceeds()
        {
            var partitionManager = new InMemoryPartitionManager();
            var ownershipList    = new List <PartitionOwnership>();
            var ownership        =
                new PartitionOwnership
                (
                    "eventHubName",
                    "consumerGroup",
                    "ownerIdentifier",
                    "partitionId"
                );

            ownershipList.Add(ownership);

            await partitionManager.ClaimOwnershipAsync(ownershipList);

            var storedOwnership = await partitionManager.ListOwnershipAsync("eventHubName", "consumerGroup");

            Assert.That(storedOwnership, Is.Not.Null);
            Assert.That(storedOwnership.Count, Is.EqualTo(1));
            Assert.That(storedOwnership.Single(), Is.EqualTo(ownership));
        }
示例#10
0
        public async Task PartitionProcessorCanCreateACheckpointFromPartitionContext()
        {
            await using (EventHubScope scope = await EventHubScope.CreateAsync(1))
            {
                var connectionString = TestEnvironment.BuildConnectionStringForEventHub(scope.EventHubName);

                await using (var client = new EventHubClient(connectionString))
                {
                    // Send some events.

                    EventData lastEvent;
                    var       dummyEvent = new EventData(Encoding.UTF8.GetBytes("I'm dummy."));

                    var partitionId = (await client.GetPartitionIdsAsync()).First();

                    await using (EventHubProducer producer = client.CreateProducer())
                        await using (EventHubConsumer consumer = client.CreateConsumer(EventHubConsumer.DefaultConsumerGroupName, partitionId, EventPosition.Earliest))
                        {
                            // Send a few events.  We are only interested in the last one of them.

                            var dummyEventsCount = 10;

                            for (int i = 0; i < dummyEventsCount; i++)
                            {
                                await producer.SendAsync(dummyEvent);
                            }

                            // Receive the events; because there is some non-determinism in the messaging flow, the
                            // sent events may not be immediately available.  Allow for a small number of attempts to receive, in order
                            // to account for availability delays.

                            var receivedEvents = new List <EventData>();
                            var index          = 0;

                            while ((receivedEvents.Count < dummyEventsCount) && (++index < ReceiveRetryLimit))
                            {
                                receivedEvents.AddRange(await consumer.ReceiveAsync(dummyEventsCount + 10, TimeSpan.FromMilliseconds(25)));
                            }

                            Assert.That(receivedEvents.Count, Is.EqualTo(dummyEventsCount));

                            lastEvent = receivedEvents.Last();
                        }

                    // Create a partition manager so we can retrieve the created checkpoint from it.

                    var partitionManager = new InMemoryPartitionManager();

                    // Create the event processor manager to manage our event processors.

                    var eventProcessorManager = new EventProcessorManager
                                                (
                        EventHubConsumer.DefaultConsumerGroupName,
                        client,
                        partitionManager,
                        onProcessEvents: (partitionContext, events, cancellationToken) =>
                    {
                        // Make it a list so we can safely enumerate it.

                        var eventsList = new List <EventData>(events ?? Enumerable.Empty <EventData>());

                        if (eventsList.Any())
                        {
                            partitionContext.UpdateCheckpointAsync(eventsList.Last());
                        }
                    }
                                                );

                    eventProcessorManager.AddEventProcessors(1);

                    // Start the event processors.

                    await eventProcessorManager.StartAllAsync();

                    // Make sure the event processors have enough time to stabilize and receive events.

                    await eventProcessorManager.WaitStabilization();

                    // Stop the event processors.

                    await eventProcessorManager.StopAllAsync();

                    // Validate results.

                    IEnumerable <PartitionOwnership> ownershipEnumerable = await partitionManager.ListOwnershipAsync(client.FullyQualifiedNamespace, client.EventHubName, EventHubConsumer.DefaultConsumerGroupName);

                    Assert.That(ownershipEnumerable, Is.Not.Null);
                    Assert.That(ownershipEnumerable.Count, Is.EqualTo(1));

                    PartitionOwnership ownership = ownershipEnumerable.Single();

                    Assert.That(ownership.Offset.HasValue, Is.True);
                    Assert.That(ownership.Offset.Value, Is.EqualTo(lastEvent.Offset));

                    Assert.That(ownership.SequenceNumber.HasValue, Is.True);
                    Assert.That(ownership.SequenceNumber.Value, Is.EqualTo(lastEvent.SequenceNumber));
                }
            }
        }