/// <summary> /// Initializes a new instance of the <see cref="AmqpProducer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub to which events will be published.</param> /// <param name="partitionId">The identifier of the Event Hub partition to which it is bound; if unbound, <c>null</c>.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpProducer(string eventHubName, string partitionId, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EventHubName = eventHubName; PartitionId = partitionId; RetryPolicy = retryPolicy; ConnectionScope = connectionScope; MessageConverter = messageConverter; SendLink = new FaultTolerantAmqpObject <SendingAmqpLink>( timeout => CreateLinkAndEnsureProducerStateAsync(partitionId, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="EventData" /> from a specific Event Hub partition, in the context /// of a specific consumer group. /// /// A consumer may be exclusive, which asserts ownership over the partition for the consumer /// group to ensure that only one consumer from that group is reading the from the partition. /// These exclusive consumers are sometimes referred to as "Epoch Consumers." /// /// A consumer may also be non-exclusive, allowing multiple consumers from the same consumer /// group to be actively reading events from the partition. These non-exclusive consumers are /// sometimes referred to as "Non-epoch Consumers." /// /// Designating a consumer as exclusive may be specified by setting the <paramref name="ownerLevel" />. /// When <c>null</c>, consumers are created as non-exclusive. /// </summary> /// /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="eventPosition">The position within the partition where the consumer should begin reading events.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public abstract TransportConsumer CreateConsumer(string consumerGroup, string partitionId, EventPosition eventPosition, EventHubsRetryPolicy retryPolicy, bool trackLastEnqueuedEventProperties, long?ownerLevel, uint?prefetchCount);
/// <summary> /// Initializes a new instance of the <see cref="AmqpConsumer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub from which events will be consumed.</param> /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="consumerOptions">The set of active options for the consumer that will make use of the link.</param> /// <param name="eventPosition">The position of the event in the partition where the consumer should begin reading.</param> /// <param name="connectionScope">The AMQP connection context for operations .</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpConsumer(string eventHubName, string consumerGroup, string partitionId, EventPosition eventPosition, EventHubConsumerClientOptions consumerOptions, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNullOrEmpty(consumerGroup, nameof(consumerGroup)); Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId)); Argument.AssertNotNull(consumerOptions, nameof(EventHubConsumerClientOptions)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EventHubName = eventHubName; ConsumerGroup = consumerGroup; PartitionId = partitionId; Options = consumerOptions; ConnectionScope = connectionScope; RetryPolicy = retryPolicy; MessageConverter = messageConverter; ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(timeout => ConnectionScope.OpenConsumerLinkAsync(consumerGroup, partitionId, eventPosition, consumerOptions, timeout, CancellationToken.None), link => link.SafeClose()); }
internal override Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken = default) { GetPartitionPropertiesInvokedWith = retryPolicy; return(Task.FromResult(default(PartitionProperties))); }
public override Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken = default) { GetPartitionPropertiesCalledForId = partitionId; return(Task.FromResult(default(PartitionProperties))); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpProducer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub to which events will be published.</param> /// <param name="partitionId">The identifier of the Event Hub partition to which it is bound; if unbound, <c>null</c>.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// <param name="requestedFeatures">The flags specifying the set of special transport features that should be opted-into.</param> /// <param name="partitionOptions">The set of options, if any, that should be considered when initializing the producer.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpProducer(string eventHubName, string partitionId, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy, TransportProducerFeatures requestedFeatures = TransportProducerFeatures.None, PartitionPublishingOptions partitionOptions = null) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EventHubName = eventHubName; PartitionId = partitionId; RetryPolicy = retryPolicy; ConnectionScope = connectionScope; MessageConverter = messageConverter; ActiveFeatures = requestedFeatures; ActiveOptions = partitionOptions?.Clone() ?? new PartitionPublishingOptions(); SendLink = new FaultTolerantAmqpObject <SendingAmqpLink>( timeout => CreateLinkAndEnsureProducerStateAsync(partitionId, ActiveOptions, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="EventData" /> from a specific Event Hub partition, in the context /// of a specific consumer group. /// /// A consumer may be exclusive, which asserts ownership over the partition for the consumer /// group to ensure that only one consumer from that group is reading the from the partition. /// These exclusive consumers are sometimes referred to as "Epoch Consumers." /// /// A consumer may also be non-exclusive, allowing multiple consumers from the same consumer /// group to be actively reading events from the partition. These non-exclusive consumers are /// sometimes referred to as "Non-epoch Consumers." /// /// Designating a consumer as exclusive may be specified by setting the <paramref name="ownerLevel" />. /// When <c>null</c>, consumers are created as non-exclusive. /// </summary> /// /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="consumerIdentifier">The identifier to associate with the consumer; if <c>null</c> or <see cref="string.Empty" />, a random identifier will be generated.</param> /// <param name="eventPosition">The position within the partition where the consumer should begin reading events.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="invalidateConsumerWhenPartitionStolen">Indicates whether or not the consumer should consider itself invalid when a partition is stolen.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="prefetchSizeInBytes">The cache size of the prefetch queue. When set, the link makes a best effort to ensure prefetched messages fit into the specified size.</param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public override TransportConsumer CreateConsumer(string consumerGroup, string partitionId, string consumerIdentifier, EventPosition eventPosition, EventHubsRetryPolicy retryPolicy, bool trackLastEnqueuedEventProperties, bool invalidateConsumerWhenPartitionStolen, long?ownerLevel, uint?prefetchCount, long?prefetchSizeInBytes) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpConsumer ( EventHubName, consumerGroup, partitionId, consumerIdentifier, eventPosition, trackLastEnqueuedEventProperties, invalidateConsumerWhenPartitionStolen, ownerLevel, prefetchCount, prefetchSizeInBytes, ConnectionScope, MessageConverter, retryPolicy )); }
/// <summary> /// Initializes a new instance of the <see cref="BlobsCheckpointStore" /> class. /// </summary> /// /// <param name="blobContainerClient">The client used to interact with the Azure Blob Storage service.</param> /// <param name="retryPolicy">The retry policy to use as the basis for interacting with the Storage Blobs service.</param> /// <param name="functionId">The function id for diagnostic messages.</param> /// <param name="logger">The logger to use for diagnostic messages.</param> /// public BlobsCheckpointStore(BlobContainerClient blobContainerClient, EventHubsRetryPolicy retryPolicy, string functionId, ILogger logger) : this(blobContainerClient, retryPolicy, initializeWithLegacyCheckpoints : true) { _functionId = functionId; _logger = logger; }
/// <summary> /// Initializes a new instance of the <see cref="BlobsCheckpointStore" /> class. /// </summary> /// /// <param name="blobContainerClient">The client used to interact with the Azure Blob Storage service.</param> /// <param name="retryPolicy">The retry policy to use as the basis for interacting with the Storage Blobs service.</param> /// <param name="functionId">The function id for diagnostic messages.</param> /// <param name="logger">The logger to use for diagnostic messages.</param> /// public BlobsCheckpointStore(BlobContainerClient blobContainerClient, EventHubsRetryPolicy retryPolicy, string functionId, ILogger logger) : this(blobContainerClient, retryPolicy) { _functionId = functionId; _logger = logger; }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="EventData" /> from a specific Event Hub partition, in the context /// of a specific consumer group. /// /// A consumer may be exclusive, which asserts ownership over the partition for the consumer /// group to ensure that only one consumer from that group is reading the from the partition. /// These exclusive consumers are sometimes referred to as "Epoch Consumers." /// /// A consumer may also be non-exclusive, allowing multiple consumers from the same consumer /// group to be actively reading events from the partition. These non-exclusive consumers are /// sometimes referred to as "Non-epoch Consumers." /// /// Designating a consumer as exclusive may be specified by setting the <paramref name="ownerLevel" />. /// When <c>null</c>, consumers are created as non-exclusive. /// </summary> /// /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="eventPosition">The position within the partition where the consumer should begin reading events.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="invalidateConsumerWhenPartitionStolen">Indicates whether or not the consumer should consider itself invalid when a partition is stolen.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="prefetchSizeInBytes">The cache size of the prefetch queue. When set, the link makes a best effort to ensure prefetched messages fit into the specified size.</param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public abstract TransportConsumer CreateConsumer(string consumerGroup, string partitionId, EventPosition eventPosition, EventHubsRetryPolicy retryPolicy, bool trackLastEnqueuedEventProperties, bool invalidateConsumerWhenPartitionStolen, long?ownerLevel, uint?prefetchCount, long?prefetchSizeInBytes);
/// <summary> /// Initializes a new instance of the <see cref="BlobsCheckpointStore"/> class. /// </summary> /// /// <param name="blobContainerClient">The client used to interact with the Azure Blob Storage service.</param> /// <param name="retryPolicy">The retry policy to use as the basis for interacting with the Storage Blobs service.</param> /// public BlobsCheckpointStore(BlobContainerClient blobContainerClient, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNull(blobContainerClient, nameof(blobContainerClient)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); ContainerClient = blobContainerClient; RetryPolicy = retryPolicy; }
/// <summary> /// Initializes a new instance of the <see cref="BlobsCheckpointStore" /> class. /// </summary> /// /// <param name="blobContainerClient">The client used to interact with the Azure Blob Storage service.</param> /// <param name="retryPolicy">The retry policy to use as the basis for interacting with the Storage Blobs service.</param> /// public BlobsCheckpointStore(BlobContainerClient blobContainerClient, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNull(blobContainerClient, nameof(blobContainerClient)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); ContainerClient = blobContainerClient; RetryPolicy = retryPolicy; BlobsCheckpointStoreCreated(nameof(BlobsCheckpointStore), blobContainerClient.AccountName, blobContainerClient.Name); }
/// <summary> /// Initializes a new instance of the <see cref="BlobsCheckpointStore" /> class. /// </summary> /// /// <param name="blobContainerClient">The client used to interact with the Azure Blob Storage service.</param> /// <param name="retryPolicy">The retry policy to use as the basis for interacting with the Storage Blobs service.</param> /// <param name="initializeWithLegacyCheckpoints">Indicates whether to read legacy checkpoint when no current version checkpoint is available for a partition.</param> /// public BlobsCheckpointStore(BlobContainerClient blobContainerClient, EventHubsRetryPolicy retryPolicy, bool initializeWithLegacyCheckpoints = false) { Argument.AssertNotNull(blobContainerClient, nameof(blobContainerClient)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); ContainerClient = blobContainerClient; RetryPolicy = retryPolicy; InitializeWithLegacyCheckpoints = initializeWithLegacyCheckpoints; BlobsCheckpointStoreCreated(nameof(BlobsCheckpointStore), blobContainerClient.AccountName, blobContainerClient.Name); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpConsumer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub from which events will be consumed.</param> /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="consumerIdentifier">The identifier to associate with the consumer; if <c>null</c> or <see cref="string.Empty" />, a random identifier will be generated.</param> /// <param name="eventPosition">The position of the event in the partition where the consumer should begin reading.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="prefetchSizeInBytes">The cache size of the prefetch queue. When set, the link makes a best effort to ensure prefetched messages fit into the specified size.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="invalidateConsumerWhenPartitionStolen">Indicates whether or not the consumer should consider itself invalid when a partition is stolen.</param> /// <param name="connectionScope">The AMQP connection context for operations .</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpConsumer(string eventHubName, string consumerGroup, string partitionId, string consumerIdentifier, EventPosition eventPosition, bool trackLastEnqueuedEventProperties, bool invalidateConsumerWhenPartitionStolen, long?ownerLevel, uint?prefetchCount, long?prefetchSizeInBytes, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNullOrEmpty(consumerGroup, nameof(consumerGroup)); Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); if (string.IsNullOrEmpty(consumerIdentifier)) { consumerIdentifier = Guid.NewGuid().ToString(); } EventHubName = eventHubName; ConsumerGroup = consumerGroup; PartitionId = partitionId; Identifier = consumerIdentifier; CurrentEventPosition = eventPosition; TrackLastEnqueuedEventProperties = trackLastEnqueuedEventProperties; InvalidateConsumerWhenPartitionStolen = invalidateConsumerWhenPartitionStolen; ConnectionScope = connectionScope; RetryPolicy = retryPolicy; MessageConverter = messageConverter; ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>( timeout => CreateConsumerLinkAsync( consumerGroup, partitionId, consumerIdentifier, CurrentEventPosition, prefetchCount ?? DefaultPrefetchCount, prefetchSizeInBytes, ownerLevel, trackLastEnqueuedEventProperties, timeout, CancellationToken.None), CloseConsumerLink); }
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="EventData" /> to the Event Hub. /// </summary> /// /// <param name="partitionId">The identifier of the partition to which the transport producer should be bound; if <c>null</c>, the producer is unbound.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportProducer"/> configured in the requested manner.</returns> /// public override TransportProducer CreateProducer(string partitionId, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpProducer ( EventHubName, partitionId, ConnectionScope, MessageConverter, retryPolicy )); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpConsumer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub from which events will be consumed.</param> /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="eventPosition">The position of the event in the partition where the consumer should begin reading.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// <param name="prefetchSizeInBytes">The cache size of the prefetch queue. When set, the link makes a best effort to ensure prefetched messages fit into the specified size.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="connectionScope">The AMQP connection context for operations .</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpConsumer(string eventHubName, string consumerGroup, string partitionId, EventPosition eventPosition, bool trackLastEnqueuedEventProperties, long?ownerLevel, uint?prefetchCount, long?prefetchSizeInBytes, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNullOrEmpty(consumerGroup, nameof(consumerGroup)); Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); EventHubName = eventHubName; ConsumerGroup = consumerGroup; PartitionId = partitionId; CurrentEventPosition = eventPosition; TrackLastEnqueuedEventProperties = trackLastEnqueuedEventProperties; ConnectionScope = connectionScope; RetryPolicy = retryPolicy; MessageConverter = messageConverter; ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>( timeout => CreateConsumerLinkAsync( consumerGroup, partitionId, CurrentEventPosition, prefetchCount ?? DefaultPrefetchCount, prefetchSizeInBytes, ownerLevel, trackLastEnqueuedEventProperties, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); }); }
/// <summary> /// Initializes a new instance of the <see cref="TransportProducerPool" /> class. /// </summary> /// /// <param name="connection">The <see cref="EventHubConnection" /> connection to use for communication with the Event Hubs service.</param> /// <param name="retryPolicy">The policy to use for determining retry behavior for when an operation fails.</param> /// <param name="pool">The pool of <see cref="PoolItem" /> that is going to be used to store the partition specific <see cref="TransportProducer" />.</param> /// <param name="performExpirationPeriod">The period after which <see cref="CreateExpirationTimerCallback" /> is run. Overrides <see cref="DefaultPerformExpirationPeriod" />.</param> /// <param name="eventHubProducer">An abstracted Event Hub transport-specific producer that is associated with the Event Hub gateway rather than a specific partition.</param> /// public TransportProducerPool(EventHubConnection connection, EventHubsRetryPolicy retryPolicy, ConcurrentDictionary <string, PoolItem> pool = default, TimeSpan?performExpirationPeriod = default, TransportProducer eventHubProducer = default) { Connection = connection; RetryPolicy = retryPolicy; Pool = pool ?? new ConcurrentDictionary <string, PoolItem>(); performExpirationPeriod ??= DefaultPerformExpirationPeriod; EventHubProducer = eventHubProducer ?? connection.CreateTransportProducer(null, retryPolicy); ExpirationTimer = new Timer(CreateExpirationTimerCallback(), null, performExpirationPeriod.Value, performExpirationPeriod.Value); }
public void RespectsConnectionOptionsForConsumer(string expectedPathName, string connectionString) { var testEndpoint = new Uri("http://mycustomendpoint.com"); EventHubOptions options = new EventHubOptions { ConnectionOptions = new EventHubConnectionOptions { CustomEndpointAddress = testEndpoint }, RetryOptions = new EventHubsRetryOptions { MaximumRetries = 10 } }; options.AddReceiver(expectedPathName, connectionString); var configuration = CreateConfiguration(); var factory = new EventHubClientFactory(configuration, Mock.Of <AzureComponentFactory>(), Options.Create(options), new DefaultNameResolver(configuration)); var consumer = factory.GetEventHubConsumerClient(expectedPathName, null, "consumer"); var consumerClient = (EventHubConsumerClient)typeof(EventHubConsumerClientImpl) .GetField("_client", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(consumer); EventHubConnection connection = (EventHubConnection)typeof(EventHubConsumerClient) .GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(consumerClient); EventHubConnectionOptions connectionOptions = (EventHubConnectionOptions)typeof(EventHubConnection) .GetProperty("Options", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(connection); Assert.AreEqual(testEndpoint, connectionOptions.CustomEndpointAddress); EventHubsRetryPolicy retryPolicy = (EventHubsRetryPolicy)typeof(EventHubConsumerClient) .GetProperty("RetryPolicy", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(consumerClient); // Reflection was still necessary here because BasicRetryOptions (which is the concrete derived type) // is internal. EventHubsRetryOptions retryOptions = (EventHubsRetryOptions)retryPolicy.GetType() .GetProperty("Options", BindingFlags.Public | BindingFlags.Instance) .GetValue(retryPolicy); Assert.AreEqual(10, retryOptions.MaximumRetries); Assert.AreEqual(expectedPathName, consumer.EventHubName); }
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="EventData" /> to the Event Hub. /// </summary> /// /// <param name="partitionId">The identifier of the partition to which the transport producer should be bound; if <c>null</c>, the producer is unbound.</param> /// <param name="requestedFeatures">The flags specifying the set of special transport features that should be opted-into.</param> /// <param name="partitionOptions">The set of options, if any, that should be considered when initializing the producer.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportProducer"/> configured in the requested manner.</returns> /// public override TransportProducer CreateProducer(string partitionId, TransportProducerFeatures requestedFeatures, PartitionPublishingOptions partitionOptions, EventHubsRetryPolicy retryPolicy) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpProducer ( EventHubName, partitionId, ConnectionScope, MessageConverter, retryPolicy, requestedFeatures, partitionOptions )); }
/// <summary> /// Initializes a new instance of the <see cref="AmqpProducer"/> class. /// </summary> /// /// <param name="eventHubName">The name of the Event Hub to which events will be published.</param> /// <param name="partitionId">The identifier of the Event Hub partition to which it is bound; if unbound, <c>null</c>.</param> /// <param name="producerIdentifier">The identifier to associate with the consumer; if <c>null</c> or <see cref="string.Empty" />, a random identifier will be generated.</param> /// <param name="connectionScope">The AMQP connection context for operations.</param> /// <param name="messageConverter">The converter to use for translating between AMQP messages and client types.</param> /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param> /// <param name="requestedFeatures">The flags specifying the set of special transport features that should be opted-into.</param> /// <param name="partitionOptions">The set of options, if any, that should be considered when initializing the producer.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpProducer(string eventHubName, string partitionId, string producerIdentifier, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter, EventHubsRetryPolicy retryPolicy, TransportProducerFeatures requestedFeatures = TransportProducerFeatures.None, PartitionPublishingOptionsInternal partitionOptions = null) { Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(connectionScope, nameof(connectionScope)); Argument.AssertNotNull(messageConverter, nameof(messageConverter)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); if (string.IsNullOrEmpty(producerIdentifier)) { producerIdentifier = Guid.NewGuid().ToString(); } EventHubName = eventHubName; PartitionId = partitionId; Identifier = producerIdentifier; RetryPolicy = retryPolicy; ConnectionScope = connectionScope; MessageConverter = messageConverter; ActiveFeatures = requestedFeatures; ActiveOptions = partitionOptions?.Clone() ?? new PartitionPublishingOptionsInternal(); SendLink = new FaultTolerantAmqpObject <SendingAmqpLink>( timeout => CreateLinkAndEnsureProducerStateAsync(partitionId, producerIdentifier, ActiveOptions, timeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); EventHubsEventSource.Log.FaultTolerantAmqpObjectClose(nameof(SendingAmqpLink), "", EventHubName, "", PartitionId, link.TerminalException?.Message); }); }
/// <summary> /// Creates a consumer strongly aligned with the active protocol and transport, responsible /// for reading <see cref="EventData" /> from a specific Event Hub partition, in the context /// of a specific consumer group. /// /// A consumer may be exclusive, which asserts ownership over the partition for the consumer /// group to ensure that only one consumer from that group is reading the from the partition. /// These exclusive consumers are sometimes referred to as "Epoch Consumers." /// /// A consumer may also be non-exclusive, allowing multiple consumers from the same consumer /// group to be actively reading events from the partition. These non-exclusive consumers are /// sometimes referred to as "Non-epoch Consumers." /// /// Designating a consumer as exclusive may be specified by setting the <paramref name="ownerLevel" />. /// When <c>null</c>, consumers are created as non-exclusive. /// </summary> /// /// <param name="consumerGroup">The name of the consumer group this consumer is associated with. Events are read in the context of this group.</param> /// <param name="partitionId">The identifier of the Event Hub partition from which events will be received.</param> /// <param name="eventPosition">The position within the partition where the consumer should begin reading events.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// <param name="trackLastEnqueuedEventInformation">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested. If <c>null</c> a default will be used.</param> /// /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns> /// public override TransportConsumer CreateConsumer(string consumerGroup, string partitionId, EventPosition eventPosition, EventHubsRetryPolicy retryPolicy, bool trackLastEnqueuedEventInformation, long?ownerLevel, uint?prefetchCount) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); return(new AmqpConsumer ( EventHubName, consumerGroup, partitionId, eventPosition, trackLastEnqueuedEventInformation, ownerLevel, prefetchCount, ConnectionScope, MessageConverter, retryPolicy )); }
/// <summary> /// Retrieves information about a specific partition for an Event Hub, including elements that describe the available /// events in the partition event stream. /// </summary> /// /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param> /// <param name="retryPolicy">The retry policy to use as the basis for retrieving the information.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>The set of information for the requested partition under the Event Hub this client is associated with.</returns> /// public override async Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken) { Argument.AssertNotClosed(_closed, nameof(AmqpClient)); Argument.AssertNotNullOrEmpty(partitionId, nameof(partitionId)); Argument.AssertNotNull(retryPolicy, nameof(retryPolicy)); var failedAttemptCount = 0; var retryDelay = default(TimeSpan?); var token = default(string); var link = default(RequestResponseAmqpLink); var stopWatch = ValueStopwatch.StartNew(); try { var tryTimeout = retryPolicy.CalculateTryTimeout(0); while (!cancellationToken.IsCancellationRequested) { try { EventHubsEventSource.Log.GetPartitionPropertiesStart(EventHubName, partitionId); // Create the request message and the management link. token = await AcquireAccessTokenAsync(cancellationToken).ConfigureAwait(false); using AmqpMessage request = MessageConverter.CreatePartitionPropertiesRequest(EventHubName, partitionId, token); if (!ManagementLink.TryGetOpenedObject(out link)) { link = await ManagementLink.GetOrCreateAsync(UseMinimum(ConnectionScope.SessionTimeout, tryTimeout.CalculateRemaining(stopWatch.GetElapsedTime())), cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Send the request and process the response. using AmqpMessage response = await link.RequestAsync(request, cancellationToken).ConfigureAwait(false); AmqpError.ThrowIfErrorResponse(response, EventHubName); return(MessageConverter.CreatePartitionPropertiesFromResponse(response)); } catch (Exception ex) { Exception activeEx = ex.TranslateServiceException(EventHubName); // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop. // Otherwise, mark the exception as active and break out of the loop. ++failedAttemptCount; retryDelay = retryPolicy.CalculateRetryDelay(activeEx, failedAttemptCount); if ((retryDelay.HasValue) && (!ConnectionScope.IsDisposed) && (!_closed) && (!cancellationToken.IsCancellationRequested)) { EventHubsEventSource.Log.GetPartitionPropertiesError(EventHubName, partitionId, activeEx.Message); await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false); tryTimeout = retryPolicy.CalculateTryTimeout(failedAttemptCount); stopWatch = ValueStopwatch.StartNew(); } else if (ex is AmqpException) { ExceptionDispatchInfo.Capture(activeEx).Throw(); } else { throw; } } } // If no value has been returned nor exception thrown by this point, // then cancellation has been requested. throw new TaskCanceledException(); } catch (Exception ex) { EventHubsEventSource.Log.GetPartitionPropertiesError(EventHubName, partitionId, ex.Message); throw; } finally { EventHubsEventSource.Log.GetPartitionPropertiesComplete(EventHubName, partitionId); } }
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="EventData" /> to the Event Hub. /// </summary> /// /// <param name="partitionId">The identifier of the partition to which the transport producer should be bound; if <c>null</c>, the producer is unbound.</param> /// <param name="producerIdentifier">The identifier to associate with the consumer; if <c>null</c> or <see cref="string.Empty" />, a random identifier will be generated.</param> /// <param name="requestedFeatures">The flags specifying the set of special transport features that should be opted-into.</param> /// <param name="partitionOptions">The set of options, if any, that should be considered when initializing the producer.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportProducer"/> configured in the requested manner.</returns> /// public abstract TransportProducer CreateProducer(string partitionId, string producerIdentifier, TransportProducerFeatures requestedFeatures, PartitionPublishingOptionsInternal partitionOptions, EventHubsRetryPolicy retryPolicy);
internal override TransportProducer CreateTransportProducer(string partitionId, TransportProducerFeatures requestedFeatures, PartitionPublishingOptions partitionOptions, EventHubsRetryPolicy retryPolicy) => TransportProducerFactory();
/// <summary> /// Creates a producer strongly aligned with the active protocol and transport, /// responsible for publishing <see cref="EventData" /> to the Event Hub. /// </summary> /// /// <param name="partitionId">The identifier of the partition to which the transport producer should be bound; if <c>null</c>, the producer is unbound.</param> /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param> /// /// <returns>A <see cref="TransportProducer"/> configured in the requested manner.</returns> /// public abstract TransportProducer CreateProducer(string partitionId, EventHubsRetryPolicy retryPolicy);
/// <summary> /// Retrieves information about an Event Hub, including the number of partitions present /// and their identifiers. /// </summary> /// /// <param name="retryPolicy">The retry policy to use as the basis for retrieving the information.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>The set of information for the Event Hub that this client is associated with.</returns> /// public abstract Task <EventHubProperties> GetPropertiesAsync(EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken);
internal override TransportProducer CreateTransportProducer(string partitionId, EventHubsRetryPolicy retryPolicy) => TransportProducerFactory();
/// <summary> /// Retrieves information about a specific partition for an Event Hub, including elements that describe the available /// events in the partition event stream. /// </summary> /// /// <param name="partitionId">The unique identifier of a partition associated with the Event Hub.</param> /// <param name="retryPolicy">The retry policy to use as the basis for retrieving the information.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>The set of information for the requested partition under the Event Hub this client is associated with.</returns> /// public abstract Task <PartitionProperties> GetPartitionPropertiesAsync(string partitionId, EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken);
internal async override Task <string[]> GetPartitionIdsAsync(EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken = default) { GetPartitionIdsInvokedWith = retryPolicy; return(await base.GetPartitionIdsAsync(retryPolicy, cancellationToken)); }
internal override Task <EventHubProperties> GetPropertiesAsync(EventHubsRetryPolicy retryPolicy, CancellationToken cancellationToken = default) { GetPropertiesInvokedWith = retryPolicy; return(Task.FromResult(new EventHubProperties(EventHubName, DateTimeOffset.Parse("2015-10-27T00:00:00Z"), new string[] { "0", "1" }))); }