public async Task OwnershipClaimSetsLastModifiedTimeAndVersion() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var ownershipList = new List<EventProcessorPartitionOwnership>(); var ownership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(ownership); await checkpointStore.ClaimOwnershipAsync(ownershipList, default); Assert.That(ownership.LastModifiedTime, Is.Not.EqualTo(default(DateTimeOffset))); Assert.That(ownership.LastModifiedTime, Is.GreaterThan(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromSeconds(5)))); Assert.That(ownership.Version, Is.Not.Null); } }
public async Task OwnershipClaimFailsWhenVersionExistsAndOwnershipDoesNotExist() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var ownershipList = new List<EventProcessorPartitionOwnership>(); var eTaggyOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = "ETag" }; ownershipList.Add(eTaggyOwnership); await checkpointStore.ClaimOwnershipAsync(ownershipList, default); IEnumerable<EventProcessorPartitionOwnership> storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup", default); Assert.That(storedOwnershipList, Is.Not.Null.And.Empty); } }
public async Task FirstOwnershipClaimSucceeds() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var ownershipList = new List<EventProcessorPartitionOwnership>(); var ownership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(ownership); await checkpointStore.ClaimOwnershipAsync(ownershipList, default); IEnumerable<EventProcessorPartitionOwnership> storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup", default); Assert.That(storedOwnershipList, Is.Not.Null); Assert.That(storedOwnershipList.Count, Is.EqualTo(1)); Assert.That(storedOwnershipList.Single().IsEquivalentTo(ownership), Is.True); } }
public async Task CheckReturnedEtagContainsSingleQuotes() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { // A regular expression used to capture strings enclosed in double quotes. Regex s_doubleQuotesExpression = new Regex("\"(.*)\"", RegexOptions.Compiled); var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var ownershipList = new List<EventProcessorPartitionOwnership>(); var ownership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(ownership); IEnumerable<EventProcessorPartitionOwnership> claimedOwnership = await checkpointStore.ClaimOwnershipAsync(ownershipList, default); IEnumerable<EventProcessorPartitionOwnership> storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup", default); var claimedOwnershipMatch = s_doubleQuotesExpression.Match(claimedOwnership.First().Version); var storedOwnershipListMatch = s_doubleQuotesExpression.Match(storedOwnershipList.First().Version); Assert.That(claimedOwnershipMatch.Success, Is.False); Assert.That(storedOwnershipListMatch.Success, Is.False); } }
/// <summary> /// Compares ownership information between two instances to determine if the /// instances represent the same ownership. /// </summary> /// /// <param name="instance">The instance that this method was invoked on.</param> /// <param name="other">The other partition ownership to consider.</param> /// /// <returns><c>true</c>, if the two ownership are structurally equivalent; otherwise, <c>false</c>.</returns> /// public static bool IsEquivalentTo(this EventProcessorPartitionOwnership instance, EventProcessorPartitionOwnership other) { // If the ownership are the same instance, they're equal. This should only happen // if both are null or they are the exact same instance. if (Object.ReferenceEquals(instance, other)) { return(true); } // If one or the other is null, then they cannot be equal, since we know that // they are not both null. if ((instance == null) || (other == null)) { return(false); } // If the contents of each attribute are equal, the instances are // equal. return ( instance.FullyQualifiedNamespace == other.FullyQualifiedNamespace && instance.EventHubName == other.EventHubName && instance.ConsumerGroup == other.ConsumerGroup && instance.OwnerIdentifier == other.OwnerIdentifier && instance.PartitionId == other.PartitionId && instance.LastModifiedTime == other.LastModifiedTime && instance.Version == other.Version ); }
/// <inheritdoc /> public async Task <IEnumerable <EventProcessorPartitionOwnership> > ListOwnershipAsync(CancellationToken cancellationToken) { EventProcessorPartitionOwnership[] results; var acquiredLock = false; _listOwnershipCounter.Increment(); try { await _collectionControl.WaitAsync(cancellationToken).ConfigureAwait(false); acquiredLock = true; results = new EventProcessorPartitionOwnership[_leases.Count]; var index = 0; foreach (var ownership in _leases.Values) { results[index++] = CloneOwnership(ownership); } } finally { if (acquiredLock) { _collectionControl.Release(); } } return(results); }
/// <summary> /// Clones the ownership instance /// </summary> /// <param name="ownership">The ownership to clone</param> /// <returns>The deep clone of the source ownership</returns> private static EventProcessorPartitionOwnership CloneOwnership(EventProcessorPartitionOwnership ownership) { return(new EventProcessorPartitionOwnership { ConsumerGroup = ownership.ConsumerGroup, EventHubName = ownership.EventHubName, FullyQualifiedNamespace = ownership.FullyQualifiedNamespace, LastModifiedTime = ownership.LastModifiedTime, OwnerIdentifier = ownership.OwnerIdentifier, PartitionId = ownership.PartitionId, Version = ownership.Version }); }
public async Task OwnershipClaimDoesNotInterfereWithOtherNamespaces() { await using (var storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var ownershipList = new List<EventProcessorPartitionOwnership>(); var firstOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace1", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(firstOwnership); await checkpointStore.ClaimOwnershipAsync(ownershipList, default); // Version must have been set by the checkpoint store. var version = firstOwnership.Version; ownershipList.Clear(); var secondOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace2", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = version }; ownershipList.Add(secondOwnership); Assert.That(async () => await checkpointStore.ClaimOwnershipAsync(ownershipList, default), Throws.InstanceOf<RequestFailedException>()); var storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace1", "eventHubName", "consumerGroup", default); Assert.That(storedOwnershipList, Is.Not.Null); Assert.That(storedOwnershipList.Count, Is.EqualTo(1)); Assert.That(storedOwnershipList.Single().IsEquivalentTo(firstOwnership), Is.True); } }
public async Task OwnershipClaimDoesNotInterfereWithOtherNamespaces() { var storageManager = new InMemoryCheckpointStore(); var ownershipList = new List <EventProcessorPartitionOwnership>(); var firstOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace1", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(firstOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); // Version must have been set by the storage manager. var version = firstOwnership.Version; ownershipList.Clear(); var secondOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace2", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = version }; ownershipList.Add(secondOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); IEnumerable <EventProcessorPartitionOwnership> storedOwnership1 = await storageManager.ListOwnershipAsync("namespace1", "eventHubName", "consumerGroup"); IEnumerable <EventProcessorPartitionOwnership> storedOwnership2 = await storageManager.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 OwnershipClaimSucceedsWhenVersionsValid() { var storageManager = new MockCheckPointStorage(); var ownershipList = new List <EventProcessorPartitionOwnership>(); var firstOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(firstOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); // Version must have been set by the storage manager. var version = firstOwnership.Version; ownershipList.Clear(); var secondOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = version }; ownershipList.Add(secondOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); IEnumerable <EventProcessorPartitionOwnership> storedOwnership = await storageManager.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup"); Assert.That(storedOwnership, Is.Not.Null); Assert.That(storedOwnership.Count, Is.EqualTo(1)); Assert.That(storedOwnership.Single(), Is.EqualTo(secondOwnership)); }
/// <summary> /// An shared method for populating the lease collection /// </summary> private void PopulateCollectionInternal() { var leases = new Dictionary <string, EventProcessorPartitionOwnership>(); var allPartitions = _partitionManager.GetPartitions(); foreach (var partition in allPartitions) { var isOwned = _partitionManager.IsOwner(partition); var exists = _leases.TryGetValue(partition, out var existing); var ownership = new EventProcessorPartitionOwnership { ConsumerGroup = _client.ConsumerGroup, EventHubName = _client.EventHubName, FullyQualifiedNamespace = _client.FullyQualifiedNamespace, PartitionId = partition, Version = LeaseVersion }; if (isOwned) { if (exists && string.Equals(existing.OwnerIdentifier, _client.Identifier, StringComparison.Ordinal)) { ownership.OwnerIdentifier = existing.OwnerIdentifier; ownership.LastModifiedTime = existing.LastModifiedTime; } else { ownership.OwnerIdentifier = null; ownership.LastModifiedTime = DateTimeOffset.MinValue; } } else { ownership.OwnerIdentifier = NotOwned; ownership.LastModifiedTime = _maximumDateTime; } leases.Add(partition, ownership); } _leases = leases; }
public async Task OwnershipClaimSucceedsWhenVersionIsValid() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.Instance.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobCheckpointStoreInternal(containerClient); var firstOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; await checkpointStore.ClaimOwnershipAsync(new[] { firstOwnership }, default); // The first ownership's version should have been set by the checkpoint store. var secondOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = firstOwnership.Version }; await checkpointStore.ClaimOwnershipAsync(new[] { secondOwnership }, default); var storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup", default); Assert.That(storedOwnershipList, Is.Not.Null); Assert.That(storedOwnershipList.Count, Is.EqualTo(1)); Assert.That(storedOwnershipList.Single().IsEquivalentTo(secondOwnership), Is.True); } }
public async Task OwnershipClaimFailsWhenVersionIsInvalid(string version) { var storageManager = new InMemoryCheckpointStore(); var ownershipList = new List <EventProcessorPartitionOwnership>(); var firstOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(firstOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); ownershipList.Clear(); var secondOwnership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = version }; ownershipList.Add(secondOwnership); await storageManager.ClaimOwnershipAsync(ownershipList); IEnumerable <EventProcessorPartitionOwnership> storedOwnership = await storageManager.ListOwnershipAsync("namespace", "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 storageManager = new InMemoryStorageManager(); var ownershipList = new List <EventProcessorPartitionOwnership>(); var ownership = new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId" }; ownershipList.Add(ownership); await storageManager.ClaimOwnershipAsync(ownershipList); IEnumerable <EventProcessorPartitionOwnership> storedOwnership = await storageManager.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup"); Assert.That(storedOwnership, Is.Not.Null); Assert.That(storedOwnership.Count, Is.EqualTo(1)); Assert.That(storedOwnership.Single(), Is.EqualTo(ownership)); }