public async Task FirstOwnershipClaimSucceeds()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new BlobPartitionManager(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var ownership        =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(ownership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(ownership), Is.True);
            }
        }
        public async Task OwnershipClaimSetsLastModifiedTimeAndETag()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new BlobPartitionManager(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var ownership        =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(ownership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                Assert.That(ownership.LastModifiedTime, Is.Not.Null);
                Assert.That(ownership.LastModifiedTime.Value, Is.GreaterThan(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromSeconds(5))));

                Assert.That(ownership.ETag, Is.Not.Null);
            }
        }
        public void IsEquivalentToDetectsOffset(long?offset1, long?offset2)
        {
            var first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", offset: offset1);
            var second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", offset: offset2);

            Assert.That(first.IsEquivalentTo(second), Is.False);
        }
        public void IsEquivalentToDetectsSequenceNumber(long?sequenceNumber1, long?sequenceNumber2)
        {
            var first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", sequenceNumber: sequenceNumber1);
            var second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", sequenceNumber: sequenceNumber2);

            Assert.That(first.IsEquivalentTo(second), Is.False);
        }
        public void IsEquivalentToDetectsPartitionId()
        {
            var first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId1");
            var second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId2");

            Assert.That(first.IsEquivalentTo(second), Is.False);
        }
        public async Task OwnershipClaimFailsWhenETagExistsAndOwnershipDoesNotExist()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new BlobPartitionManager(containerClient);
                var ownershipList    = new List <PartitionOwnership>();

                var eTaggyOwnership =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId",
                        offset: 2,
                        eTag: "ETag"
                    );

                ownershipList.Add(eTaggyOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Assert.That(storedOwnershipList, Is.Not.Null.And.Empty);
            }
        }
        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 partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var ownership        =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(ownership);

                IEnumerable <PartitionOwnership> claimedOwnership = await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Match claimedOwnershipMatch    = s_doubleQuotesExpression.Match(claimedOwnership.First().ETag);
                Match storedOwnershipListMatch = s_doubleQuotesExpression.Match(storedOwnershipList.First().ETag);

                Assert.That(claimedOwnershipMatch.Success, Is.False);
                Assert.That(storedOwnershipListMatch.Success, Is.False);
            }
        }
        public void IsEquivalentToDetectsLastModifiedTime()
        {
            var first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", lastModifiedTime: DateTimeOffset.Parse("1975-04-04T00:00:00Z"));
            var second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", lastModifiedTime: DateTimeOffset.Parse("1975-04-04T01:00:00Z"));

            Assert.That(first.IsEquivalentTo(second), Is.False);

            var third = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");

            Assert.That(first.IsEquivalentTo(third), Is.False);
        }
        public async Task OwnershipClaimSucceedsWhenETagIsValid()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new BlobPartitionManager(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var firstOwnership   =
                    new MockPartitionOwnership
                    (
                        "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 MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId",
                        offset: 2,
                        eTag: eTag
                    );

                ownershipList.Add(secondOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(secondOwnership), Is.True);
            }
        }
        public async Task OwnershipClaimDoesNotInterfereWithOtherNamespaces()
        {
            await using (var storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var firstOwnership   =
                    new MockPartitionOwnership
                    (
                        "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 MockPartitionOwnership
                    (
                        "namespace2",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId",
                        eTag: eTag
                    );

                ownershipList.Add(secondOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(firstOwnership), Is.True);
            }
        }
        public void IsEquivalentToDetectsEqualPartitionOwnership()
        {
            var first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", DateTimeOffset.Parse("1975-04-04T00:00:00Z"), "eTag");
            var second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", DateTimeOffset.Parse("1975-04-04T00:00:00Z"), "eTag");

            Assert.That(first.IsEquivalentTo(second), Is.True);

            // Set the optional parameters to null.

            first  = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");
            second = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");

            Assert.That(first.IsEquivalentTo(second), Is.True);
        }
        public async Task OwnershipClaimFailsWhenETagIsInvalid(string eTag)
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var firstOwnership   =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(firstOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                ownershipList.Clear();

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

                ownershipList.Add(secondOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

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

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(firstOwnership), Is.True);
            }
        }
        public async Task CheckpointUpdateUpdatesOwnershipInformation()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager  = new BlobPartitionManager(containerClient);
                var originalOwnership = new MockPartitionOwnership
                                            ("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", offset: 1, sequenceNumber: 2);

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

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

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

                // Give it a 1 second delay before updating the ownership information.  We need to do this to ensure
                // we won't end up with the same 'LastModifiedTime'.  In the InMemoryPartitionManager tests we have control
                // over it, but this time this property is entirely handled by the storage service.

                await Task.Delay(1000);

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

                // Make sure the ownership has changed.

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

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

                PartitionOwnership storedOwnership = storedOwnershipList.Single();

                Assert.That(storedOwnership.Offset, Is.EqualTo(10));
                Assert.That(storedOwnership.SequenceNumber, Is.EqualTo(20));
                Assert.That(storedOwnership.LastModifiedTime, Is.GreaterThan(originalLastModifiedTime));
                Assert.That(storedOwnership.ETag, Is.Not.EqualTo(originalETag));
            }
        }
        public async Task CheckpointUpdateFailsWhenOwnerChanges()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager  = new BlobPartitionManager(containerClient);
                var originalOwnership = new MockPartitionOwnership
                                            ("namespace", "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.

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

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

                // Make sure the ownership hasn't changed.

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

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(originalOwnership), Is.True);

                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 void IsEquivalentToDetectsNullArgument()
        {
            var first = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");

            Assert.That(first.IsEquivalentTo(null), Is.False);
        }
        public void IsEquivalentToDetectsNullInstance()
        {
            var first = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");

            Assert.That(((EventProcessorPartitionOwnership)null).IsEquivalentTo(first), Is.False);
        }
        public void IsEquivalentToDetectsSameInstance()
        {
            var first = new MockPartitionOwnership("namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId");

            Assert.That(first.IsEquivalentTo(first), Is.True);
        }