public async Task ProducerInitializesPropertiesWhenPublishing() { 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 sendOptions = new SendEventOptions { PartitionId = partition }; var events = EventGenerator.CreateEvents(10).ToArray(); await producer.SendAsync(events, sendOptions, cancellationSource.Token); 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."); } }
public async Task ProducerCanInitializeWithPartialPartitionOptions() { await using (EventHubScope scope = await EventHubScope.CreateAsync(2)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new IdempotentProducerOptions { EnableIdempotentPartitions = true }; var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = default(string); var partitionProperties = default(PartitionPublishingProperties); // Create a producer for a small scope that will Send some events and read the properties. await using (var initialProducer = new IdempotentProducer(connectionString, options)) { partition = (await initialProducer.GetPartitionIdsAsync(cancellationSource.Token)).Last(); await initialProducer.SendAsync(EventGenerator.CreateEvents(10), new SendEventOptions { PartitionId = partition }, cancellationSource.Token); partitionProperties = await initialProducer.GetPartitionPublishingPropertiesAsync(partition); } // Create a new producer using the previously read properties to set options for the partition. options.PartitionOptions.Add(partition, new PartitionPublishingOptions { ProducerGroupId = partitionProperties.ProducerGroupId, OwnerLevel = partitionProperties.OwnerLevel }); Assert.That(options.PartitionOptions[partition].StartingSequenceNumber.HasValue, Is.False, "The partition options should not specifiy a starting sequence number."); await using var producer = new IdempotentProducer(connectionString, options); // Verify that the properties were fully initialized when using partial options. 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."); // Ensure that the state supports publishing. Assert.That(async() => await producer.SendAsync(EventGenerator.CreateEvents(10), new SendEventOptions { PartitionId = partition }, cancellationSource.Token), Throws.Nothing); } }
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."); } }
public async Task GetPartitionPublishingPropertiesAsyncReturnsProperties() { // Disable idempotent partitions to avoid a live service call. This will // still allow the pass-through invocation to be validated. var producer = new IdempotentProducer(Mock.Of <EventHubConnection>(), new IdempotentProducerOptions { EnableIdempotentPartitions = false }); using var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var readProperties = await producer.GetPartitionPublishingPropertiesAsync("0", cancellationSource.Token); Assert.That(readProperties, Is.Not.Null, "The read properties should have been created."); }
public async Task ProducerIsRejectedWithPartitionOptionsForInvalidState() { await using (EventHubScope scope = await EventHubScope.CreateAsync(2)) { var connectionString = EventHubsTestEnvironment.Instance.BuildConnectionStringForEventHub(scope.EventHubName); var options = new IdempotentProducerOptions { EnableIdempotentPartitions = true }; var cancellationSource = new CancellationTokenSource(); cancellationSource.CancelAfter(EventHubsTestEnvironment.Instance.TestExecutionTimeLimit); var partition = default(string); var partitionProperties = default(PartitionPublishingProperties); // Create a producer for a small scope that will Send some events and read the properties. await using (var initialProducer = new IdempotentProducer(connectionString, options)) { partition = (await initialProducer.GetPartitionIdsAsync(cancellationSource.Token)).Last(); await initialProducer.SendAsync(EventGenerator.CreateEvents(10), new SendEventOptions { PartitionId = partition }, cancellationSource.Token); partitionProperties = await initialProducer.GetPartitionPublishingPropertiesAsync(partition); } // Create a new producer using the previously read properties to set options for the partition. options.PartitionOptions.Add(partition, new PartitionPublishingOptions { ProducerGroupId = partitionProperties.ProducerGroupId, OwnerLevel = partitionProperties.OwnerLevel, StartingSequenceNumber = (partitionProperties.LastPublishedSequenceNumber - 5) }); await using var producer = new IdempotentProducer(connectionString, options); Assert.That(async() => await producer.SendAsync(EventGenerator.CreateEvents(10), new SendEventOptions { PartitionId = partition }, cancellationSource.Token), Throws.InstanceOf <EventHubsException>().And.Property("Reason").EqualTo(EventHubsException.FailureReason.InvalidClientState)); } }