public void ClaimOwnershipForMissingPartitionLogsClaimOwnershipError() { var partitionOwnership = new List <EventProcessorPartitionOwnership> { new EventProcessorPartitionOwnership { FullyQualifiedNamespace = FullyQualifiedNamespace, EventHubName = EventHubName, ConsumerGroup = ConsumerGroup, OwnerIdentifier = OwnershipIdentifier, PartitionId = PartitionId, LastModifiedTime = DateTime.UtcNow, Version = MatchingEtag } }; var mockBlobContainerClient = new MockBlobContainerClient().AddBlobClient($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/ownership/1", _ => { }); var target = new BlobsCheckpointStore(mockBlobContainerClient, DefaultRetryPolicy); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; Assert.That(async() => await target.ClaimOwnershipAsync(partitionOwnership, CancellationToken.None), Throws.InstanceOf <RequestFailedException>()); mockLog.Verify(m => m.ClaimOwnershipError(PartitionId, FullyQualifiedNamespace, EventHubName, ConsumerGroup, OwnershipIdentifier, It.Is <string>(e => e.Contains(BlobErrorCode.BlobNotFound.ToString())))); }
public void UpdateCheckpointLogsErrorsWhenTheBlobDoesNotExist() { var checkpoint = new EventProcessorCheckpoint { FullyQualifiedNamespace = FullyQualifiedNamespace, EventHubName = EventHubName, ConsumerGroup = ConsumerGroup, PartitionId = PartitionId, }; var expectedException = new DllNotFoundException("BOOM!"); var mockLog = new Mock <BlobEventStoreEventSource>(); var mockContainerClient = new MockBlobContainerClient().AddBlobClient($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/checkpoint/1", client => { client.UploadBlobException = expectedException; }); var target = new BlobsCheckpointStore(mockContainerClient, DefaultRetryPolicy); target.Logger = mockLog.Object; Assert.That(async() => await target.UpdateCheckpointAsync(checkpoint, new EventData(Array.Empty <byte>()), CancellationToken.None), Throws.Exception.EqualTo(expectedException)); mockLog.Verify(log => log.UpdateCheckpointError(checkpoint.PartitionId, checkpoint.FullyQualifiedNamespace, checkpoint.EventHubName, checkpoint.ConsumerGroup, expectedException.Message)); }
public void ClaimOwnershipLogsErrors() { var partitionOwnership = new List <EventProcessorPartitionOwnership> { new EventProcessorPartitionOwnership { FullyQualifiedNamespace = FullyQualifiedNamespace, EventHubName = EventHubName, ConsumerGroup = ConsumerGroup, OwnerIdentifier = OwnershipIdentifier, PartitionId = PartitionId, LastModifiedTime = DateTime.UtcNow } }; var expectedException = new DllNotFoundException("BOOM!"); var mockLog = new Mock <BlobEventStoreEventSource>(); var mockContainerClient = new MockBlobContainerClient().AddBlobClient($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/ownership/1", client => client.UploadBlobException = expectedException); var target = new BlobsCheckpointStore(mockContainerClient, DefaultRetryPolicy); target.Logger = mockLog.Object; Assert.That(async() => await target.ClaimOwnershipAsync(partitionOwnership, CancellationToken.None), Throws.Exception.EqualTo(expectedException)); mockLog.Verify(m => m.ClaimOwnershipError(PartitionId, FullyQualifiedNamespace, EventHubName, ConsumerGroup, OwnershipIdentifier, expectedException.Message)); }
public async Task ClaimOwnershipForExistingPartitionWithWrongEtagLogsOwnershipNotClaimable() { var blobInfo = BlobsModelFactory.BlobInfo(new ETag($@"""{WrongEtag}"""), DateTime.UtcNow); var partitionOwnership = new List <EventProcessorPartitionOwnership> { new EventProcessorPartitionOwnership { FullyQualifiedNamespace = FullyQualifiedNamespace, EventHubName = EventHubName, ConsumerGroup = ConsumerGroup, OwnerIdentifier = OwnershipIdentifier, PartitionId = PartitionId, LastModifiedTime = DateTime.UtcNow, Version = MatchingEtag } }; var mockContainerClient = new MockBlobContainerClient().AddBlobClient($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/ownership/1", client => client.BlobInfo = blobInfo); var target = new BlobsCheckpointStore(mockContainerClient, DefaultRetryPolicy); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; var result = await target.ClaimOwnershipAsync(partitionOwnership, CancellationToken.None); mockLog.Verify(m => m.OwnershipNotClaimable(PartitionId, FullyQualifiedNamespace, EventHubName, ConsumerGroup, OwnershipIdentifier, It.Is <string>(e => e.Contains(BlobErrorCode.ConditionNotMet.ToString())))); }
public EventHubListener( string functionId, ITriggeredFunctionExecutor executor, EventProcessorHost eventProcessorHost, bool singleDispatch, IEventHubConsumerClient consumerClient, BlobsCheckpointStore checkpointStore, EventHubOptions options, ILoggerFactory loggerFactory) { _loggerFactory = loggerFactory; _executor = executor; _eventProcessorHost = eventProcessorHost; _singleDispatch = singleDispatch; _checkpointStore = checkpointStore; _options = options; _logger = _loggerFactory.CreateLogger <EventHubListener>(); _scaleMonitor = new Lazy <EventHubsScaleMonitor>( () => new EventHubsScaleMonitor( functionId, consumerClient, checkpointStore, _loggerFactory.CreateLogger <EventHubsScaleMonitor>())); _details = $"'namespace='{eventProcessorHost?.FullyQualifiedNamespace}', eventHub='{eventProcessorHost?.EventHubName}', " + $"consumerGroup='{eventProcessorHost?.ConsumerGroup}', functionId='{functionId}', singleDispatch='{singleDispatch}'"; }
public async Task CheckpointUpdateDoesNotInterfereWithOtherNamespaces() { await using (var storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient); await checkpointStore.UpdateCheckpointAsync(new Checkpoint ("namespace1", "eventHubName", "consumerGroup", "partitionId", 10, 20)); await checkpointStore.UpdateCheckpointAsync(new Checkpoint ("namespace2", "eventHubName", "consumerGroup", "partitionId", 10, 20)); IEnumerable <Checkpoint> storedCheckpointsList1 = await checkpointStore.ListCheckpointsAsync("namespace1", "eventHubName", "consumerGroup"); IEnumerable <Checkpoint> storedCheckpointsList2 = await checkpointStore.ListCheckpointsAsync("namespace2", "eventHubName", "consumerGroup"); Assert.That(storedCheckpointsList1, Is.Not.Null); Assert.That(storedCheckpointsList1.Count, Is.EqualTo(1)); Assert.That(storedCheckpointsList2, Is.Not.Null); Assert.That(storedCheckpointsList2.Count, Is.EqualTo(1)); } }
public async Task OwnershipClaimFailsWhenETagExistsAndOwnershipDoesNotExist() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient); var ownershipList = new List <PartitionOwnership>(); var eTaggyOwnership = new PartitionOwnership ( "namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", eTag: "ETag" ); ownershipList.Add(eTaggyOwnership); await checkpointStore.ClaimOwnershipAsync(ownershipList); IEnumerable <PartitionOwnership> storedOwnershipList = await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup"); Assert.That(storedOwnershipList, Is.Not.Null.And.Empty); } }
public async Task GetCheckpointLogsInvalidCheckpoint() { var blobList = new List <BlobItem> { BlobsModelFactory.BlobItem($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/checkpoint/0", false, BlobsModelFactory.BlobItemProperties(true, lastModified: DateTime.UtcNow, eTag: new ETag(MatchingEtag)), "snapshot", new Dictionary <string, string> { { BlobMetadataKey.OwnerIdentifier, Guid.NewGuid().ToString() } }) }; var target = new BlobsCheckpointStore(new MockBlobContainerClient() { Blobs = blobList }, DefaultRetryPolicy); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; await target.ListCheckpointsAsync(FullyQualifiedNamespace, EventHubName, ConsumerGroup, CancellationToken.None); mockLog.Verify(m => m.InvalidCheckpointFound("0", FullyQualifiedNamespace, EventHubName, ConsumerGroup)); }
public async Task OwnershipClaimSetsLastModifiedTimeAndETag() { 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 <PartitionOwnership>(); var ownership = new PartitionOwnership ( "namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId" ); ownershipList.Add(ownership); await checkpointStore.ClaimOwnershipAsync(ownershipList, default); 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 async Task BlobStorageManagerCanClaimOwnership(string version) { 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> { // Null version and non-null version hit different paths of the code, calling different methods that connect // to the Storage service. new EventProcessorPartitionOwnership { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", OwnerIdentifier = "ownerIdentifier", PartitionId = "partitionId", Version = version } }; Assert.That(async () => await checkpointStore.ClaimOwnershipAsync(ownershipList, default), Throws.Nothing); } }
public async Task ListCheckpointsAsync_LogsOnInvalidCheckpoints() { var testLoggerProvider = new TestLoggerProvider(); Mock <BlobContainerClient> containerClientMock = new Mock <BlobContainerClient>(MockBehavior.Strict); containerClientMock.Setup(c => c.GetBlobsAsync(It.IsAny <BlobTraits>(), It.IsAny <BlobStates>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Returns(AsyncPageable <BlobItem> .FromPages(new[] { Page <BlobItem> .FromValues(new[] { BlobsModelFactory.BlobItem("testnamespace/testeventhubname/testconsumergroup/checkpoint/0", false, BlobsModelFactory.BlobItemProperties(false), metadata: new Dictionary <string, string>()) }, null, Mock.Of <Response>()) })); BlobsCheckpointStore store = new BlobsCheckpointStore( containerClientMock.Object, new BasicRetryPolicy(new EventHubsRetryOptions()), _functionId, testLoggerProvider.CreateLogger("TestLogger") ); await store.ListCheckpointsAsync(_namespace, _eventHubName, _consumerGroup, CancellationToken.None); var warning = testLoggerProvider.GetAllLogMessages().Single(p => p.Level == Extensions.Logging.LogLevel.Warning); var expectedWarning = "Function 'EventHubsTriggerFunction': An invalid checkpoint was found for partition: '0' of " + "FullyQualifiedNamespace: 'TestNamespace'; EventHubName: 'TestEventHubName'; ConsumerGroup: 'TestConsumerGroup'. " + "This checkpoint is not valid and will be ignored."; Assert.AreEqual(expectedWarning, warning.FormattedMessage); testLoggerProvider.ClearAllLogMessages(); }
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); } }
public async Task CheckpointUpdateFailsWhenContainerDoesNotExist() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.Instance.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, $"test-container-{Guid.NewGuid()}"); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); var checkpoint = new EventProcessorCheckpoint { FullyQualifiedNamespace = "namespace", EventHubName = "eventHubName", ConsumerGroup = "consumerGroup", PartitionId = "partitionId" }; var mockEvent = new MockEventData( eventBody: Array.Empty <byte>(), offset: 10, sequenceNumber: 20); Assert.That(async() => await checkpointStore.UpdateCheckpointAsync(checkpoint, mockEvent, default), Throws.InstanceOf <RequestFailedException>()); } }
public async Task ClaimOwnershipLogsStartAndComplete() { var partitionOwnership = new List <EventProcessorPartitionOwnership> { new EventProcessorPartitionOwnership { FullyQualifiedNamespace = FullyQualifiedNamespace, EventHubName = EventHubName, ConsumerGroup = ConsumerGroup, OwnerIdentifier = OwnershipIdentifier, PartitionId = PartitionId, LastModifiedTime = DateTime.UtcNow } }; var mockBlobContainerClient = new MockBlobContainerClient().AddBlobClient($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/ownership/1", _ => { }); var target = new BlobsCheckpointStore(mockBlobContainerClient, DefaultRetryPolicy); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; var result = await target.ClaimOwnershipAsync(partitionOwnership, CancellationToken.None); mockLog.Verify(m => m.ClaimOwnershipStart(PartitionId, FullyQualifiedNamespace, EventHubName, ConsumerGroup, OwnershipIdentifier)); mockLog.Verify(m => m.ClaimOwnershipComplete(PartitionId, FullyQualifiedNamespace, EventHubName, ConsumerGroup, OwnershipIdentifier)); }
public async Task CheckpointUpdateDoesNotInterfereWithOtherPartitions() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); await checkpointStore.UpdateCheckpointAsync(new Checkpoint ("namespace", "eventHubName", "consumerGroup", "partitionId1", 10, 20), default); await checkpointStore.UpdateCheckpointAsync(new Checkpoint ("namespace", "eventHubName", "consumerGroup", "partitionId2", 10, 20), default); IEnumerable <Checkpoint> storedCheckpointsList = await checkpointStore.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup", default); Assert.That(storedCheckpointsList, Is.Not.Null); Assert.That(storedCheckpointsList.Count, Is.EqualTo(2)); Checkpoint storedCheckpoint1 = storedCheckpointsList.First(checkpoint => checkpoint.PartitionId == "partitionId1"); Checkpoint storedCheckpoint2 = storedCheckpointsList.First(checkpoint => checkpoint.PartitionId == "partitionId2"); Assert.That(storedCheckpoint1, Is.Not.Null); Assert.That(storedCheckpoint2, Is.Not.Null); } }
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 BlobPartitionManagerCanClaimOwnership(string eTag) { 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 <PartitionOwnership> { // Null ETag and non-null ETag hit different paths of the code, calling different methods that connect // to the Storage service. new PartitionOwnership ( "namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId", eTag: eTag ) }; Assert.That(async() => await checkpointStore.ClaimOwnershipAsync(ownershipList, default), Throws.Nothing); } }
public async Task BlobPartitionManagerCanUpdateCheckpoint() { 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 <PartitionOwnership> { // Make sure the ownership exists beforehand so we hit all storage SDK calls in the checkpoint store. new PartitionOwnership ( "namespace", "eventHubName", "consumerGroup", "ownerIdentifier", "partitionId" ) }; await checkpointStore.ClaimOwnershipAsync(ownershipList, default); var checkpoint = new Checkpoint("namespace", "eventHubName", "consumerGroup", "partitionId", 10, 20); Assert.That(async() => await checkpointStore.UpdateCheckpointAsync(checkpoint, default), Throws.Nothing); } }
public async Task ListOwnershipLogsStartAndComplete() { var blobList = new List <BlobItem> { BlobsModelFactory.BlobItem($"{FullyQualifiedNamespace}/{EventHubName}/{ConsumerGroup}/ownership/{Guid.NewGuid().ToString()}", false, BlobsModelFactory.BlobItemProperties(true, lastModified: DateTime.UtcNow, eTag: new ETag(MatchingEtag)), "snapshot", new Dictionary <string, string> { { BlobMetadataKey.OwnerIdentifier, Guid.NewGuid().ToString() } }) }; var target = new BlobsCheckpointStore(new MockBlobContainerClient() { Blobs = blobList }, new BasicRetryPolicy(new EventHubsRetryOptions())); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; await target.ListOwnershipAsync(FullyQualifiedNamespace, EventHubName, ConsumerGroup, new CancellationToken()); mockLog.Verify(m => m.ListOwnershipAsyncStart(FullyQualifiedNamespace, EventHubName, ConsumerGroup)); mockLog.Verify(m => m.ListOwnershipAsyncComplete(FullyQualifiedNamespace, EventHubName, ConsumerGroup, blobList.Count)); }
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 Processor(int eventBatchMaximumCount, string consumerGroup, string connectionString, string eventHubName, EventProcessorOptions options, IEventProcessorFactory processorFactory, bool invokeProcessorAfterRecieveTimeout, Action <ExceptionReceivedEventArgs> exceptionHandler, BlobsCheckpointStore checkpointStore) : base(eventBatchMaximumCount, consumerGroup, connectionString, eventHubName, options) { ProcessorFactory = processorFactory; InvokeProcessorAfterRecieveTimeout = invokeProcessorAfterRecieveTimeout; ExceptionHandler = exceptionHandler; LeaseInfos = new ConcurrentDictionary <string, LeaseInfo>(); CheckpointStore = checkpointStore; }
public async Task StartProcessingAsync( IEventProcessorFactory processorFactory, BlobsCheckpointStore checkpointStore, CancellationToken cancellationToken) { _processorFactory = processorFactory; _checkpointStore = checkpointStore; await StartProcessingAsync(cancellationToken).ConfigureAwait(false); }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } ParameterInfo parameter = context.Parameter; EventHubTriggerAttribute attribute = parameter.GetCustomAttribute <EventHubTriggerAttribute>(inherit: false); if (attribute == null) { return(Task.FromResult <ITriggerBinding>(null)); } string resolvedEventHubName = _nameResolver.ResolveWholeString(attribute.EventHubName); string consumerGroup = attribute.ConsumerGroup ?? EventHubConsumerClient.DefaultConsumerGroupName; string resolvedConsumerGroup = _nameResolver.ResolveWholeString(consumerGroup); if (!string.IsNullOrWhiteSpace(attribute.Connection)) { var connection = _nameResolver.ResolveWholeString(attribute.Connection); var connectionString = _config.GetConnectionStringOrSetting(connection); _options.Value.AddReceiver(resolvedEventHubName, connectionString); } var eventHostListener = _options.Value.GetEventProcessorHost(resolvedEventHubName, resolvedConsumerGroup); var checkpointStoreConnectionString = _options.Value.GetCheckpointStoreConnectionString(_config, resolvedEventHubName); Func <ListenerFactoryContext, bool, Task <IListener> > createListener = (factoryContext, singleDispatch) => { var checkpointStore = new BlobsCheckpointStore( new BlobContainerClient(checkpointStoreConnectionString, _options.Value.LeaseContainerName), _options.Value.EventProcessorOptions.RetryOptions.ToRetryPolicy(), factoryContext.Descriptor.Id, _logger); IListener listener = new EventHubListener( factoryContext.Descriptor.Id, factoryContext.Executor, eventHostListener, singleDispatch, () => _options.Value.GetEventHubConsumerClient(resolvedEventHubName, consumerGroup), checkpointStore, _options.Value, _logger); return(Task.FromResult(listener)); }; #pragma warning disable 618 ITriggerBinding binding = BindingFactory.GetTriggerBinding(new EventHubTriggerBindingStrategy(), parameter, _converterManager, createListener); #pragma warning restore 618 return(Task.FromResult(binding)); }
public void ListOwnershipLogsErrorOnException() { var ex = new RequestFailedException(0, "foo", BlobErrorCode.ContainerNotFound.ToString(), null); var target = new BlobsCheckpointStore(new MockBlobContainerClient(getBlobsAsyncException: ex), DefaultRetryPolicy); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; Assert.That(async() => await target.ListOwnershipAsync(FullyQualifiedNamespace, EventHubName, ConsumerGroup, CancellationToken.None), Throws.InstanceOf <RequestFailedException>()); mockLog.Verify(m => m.ListOwnershipError(FullyQualifiedNamespace, EventHubName, ConsumerGroup, ex.Message)); }
public async Task ListCheckpointsFailsWhenContainerDoesNotExist() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, $"test-container-{Guid.NewGuid()}"); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); Assert.That(async () => await checkpointStore.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup", default), Throws.InstanceOf<RequestFailedException>()); } }
public async Task BlobStorageManagerCanListCheckpoints() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); Assert.That(async () => await checkpointStore.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup", default), Throws.Nothing); } }
public void ListCheckointsForMissingPartitionThrowsAndLogsOwnershipNotClaimable() { var ex = new RequestFailedException(0, "foo", BlobErrorCode.ContainerNotFound.ToString(), null); var target = new BlobsCheckpointStore(new MockBlobContainerClient(getBlobsAsyncException: ex), new BasicRetryPolicy(new EventHubsRetryOptions())); var mockLog = new Mock <BlobEventStoreEventSource>(); target.Logger = mockLog.Object; Assert.ThrowsAsync <RequestFailedException>(async() => await target.ListCheckpointsAsync(FullyQualifiedNamespace, EventHubName, ConsumerGroup, new CancellationToken())); }
public async Task BlobPartitionManagerCanListOwnership() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient); Assert.That(async() => await checkpointStore.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup"), Throws.Nothing); } }
public async Task ListCheckpointAsyncReturnsEmptyIEnumerableWhenThereAreNoCheckpoints() { await using (StorageScope storageScope = await StorageScope.CreateAsync()) { var storageConnectionString = StorageTestEnvironment.StorageConnectionString; var containerClient = new BlobContainerClient(storageConnectionString, storageScope.ContainerName); var checkpointStore = new BlobsCheckpointStore(containerClient, DefaultRetryPolicy); IEnumerable<EventProcessorCheckpoint> checkpoints = await checkpointStore.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup", default); Assert.That(checkpoints, Is.Not.Null.And.Empty); } }