/// <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(eventPosition, nameof(EventPosition));
            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());
        }
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpClient"/> class.
        /// </summary>
        ///
        /// <param name="host">The fully qualified host name for the Event Hubs namespace.  This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param>
        /// <param name="eventHubName">The name of the specific Event Hub to connect the client to.</param>
        /// <param name="credential">The Azure managed identity credential to use for authorization.  Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param>
        /// <param name="clientOptions">A set of options to apply when configuring the client.</param>
        /// <param name="connectionScope">The optional scope to use for AMQP connection management.  If <c>null</c>, a new scope will be created.</param>
        /// <param name="messageConverter">The optional converter to use for transforming AMQP message-related types.  If <c>null</c>, a new converter will be created.</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>
        ///
        protected AmqpClient(string host,
                             string eventHubName,
                             TokenCredential credential,
                             EventHubConnectionOptions clientOptions,
                             AmqpConnectionScope connectionScope,
                             AmqpMessageConverter messageConverter)
        {
            Argument.AssertNotNullOrEmpty(host, nameof(host));
            Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName));
            Argument.AssertNotNull(credential, nameof(credential));
            Argument.AssertNotNull(clientOptions, nameof(clientOptions));

            try
            {
                EventHubsEventSource.Log.EventHubClientCreateStart(host, eventHubName);

                ServiceEndpoint = new UriBuilder
                {
                    Scheme = clientOptions.TransportType.GetUriScheme(),
                    Host   = host
                }.Uri;

                EventHubName     = eventHubName;
                Credential       = credential;
                MessageConverter = messageConverter ?? new AmqpMessageConverter();
                ConnectionScope  = connectionScope ?? new AmqpConnectionScope(ServiceEndpoint, eventHubName, credential, clientOptions.TransportType, clientOptions.Proxy);
                ManagementLink   = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(timeout => ConnectionScope.OpenManagementLinkAsync(timeout, CancellationToken.None), link => link.SafeClose());
            }
            finally
            {
                EventHubsEventSource.Log.EventHubClientCreateComplete(host, eventHubName);
            }
        }
        /// <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>
        ///   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>
        ///   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);
        }
Beispiel #6
0
        /// <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();
            });
        }
Beispiel #7
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpEventHubClient"/> class.
        /// </summary>
        ///
        /// <param name="host">The fully qualified host name for the Event Hubs namespace.  This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param>
        /// <param name="eventHubName">The name of the specific Event Hub to connect the client to.</param>
        /// <param name="credential">The Azure managed identity credential to use for authorization.  Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param>
        /// <param name="clientOptions">A set of options to apply when configuring the client.</param>
        /// <param name="defaultRetryPolicy">The default retry policy to use if no retry options were specified in the <paramref name="clientOptions" />.</param>
        /// <param name="connectionScope">The optional scope to use for AMQP connection management.  If <c>null</c>, a new scope will be created.</param>
        /// <param name="messageConverter">The optional converter to use for transforming AMQP message-related types.  If <c>null</c>, a new converter will be created.</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>
        ///
        protected AmqpEventHubClient(string host,
                                     string eventHubName,
                                     TokenCredential credential,
                                     EventHubClientOptions clientOptions,
                                     EventHubRetryPolicy defaultRetryPolicy,
                                     AmqpConnectionScope connectionScope,
                                     AmqpMessageConverter messageConverter)
        {
            Argument.AssertNotNullOrEmpty(host, nameof(host));
            Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName));
            Argument.AssertNotNull(credential, nameof(credential));
            Argument.AssertNotNull(clientOptions, nameof(clientOptions));
            Argument.AssertNotNull(defaultRetryPolicy, nameof(defaultRetryPolicy));

            try
            {
                EventHubsEventSource.Log.EventHubClientCreateStart(host, eventHubName);

                EventHubName     = eventHubName;
                Credential       = credential;
                MessageConverter = messageConverter ?? new AmqpMessageConverter();

                if (connectionScope == null)
                {
                    var endpointBuilder = new UriBuilder
                    {
                        Scheme = clientOptions.TransportType.GetUriScheme(),
                        Host   = host
                    };

                    connectionScope = new AmqpConnectionScope(endpointBuilder.Uri, eventHubName, credential, clientOptions.TransportType, clientOptions.Proxy);
                }

                ConnectionScope = connectionScope;
                ManagementLink  = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(timeout => ConnectionScope.OpenManagementLinkAsync(timeout, CancellationToken.None), link => link.SafeClose());

                _retryPolicy = defaultRetryPolicy;
                _tryTimeout  = _retryPolicy.CalculateTryTimeout(0);
            }
            finally
            {
                EventHubsEventSource.Log.EventHubClientCreateComplete(host, eventHubName);
            }
        }
Beispiel #8
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpEventHubConsumer"/> class.
        /// </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="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>
        /// <param name="lastEnqueuedEventProperties">The set of properties for the last event enqueued in a partition; if not requested in the consumer options, it is expected that this is <c>null</c>.</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 AmqpEventHubConsumer(string consumerGroup,
                                    string partitionId,
                                    EventPosition eventPosition,
                                    EventHubConsumerOptions consumerOptions,
                                    AmqpConnectionScope connectionScope,
                                    AmqpMessageConverter messageConverter,
                                    EventHubRetryPolicy retryPolicy,
                                    LastEnqueuedEventProperties lastEnqueuedEventProperties) : base(lastEnqueuedEventProperties)
        {
            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));

            ConnectionScope  = connectionScope;
            MessageConverter = messageConverter;
            ReceiveLink      = new FaultTolerantAmqpObject <ReceivingAmqpLink>(timeout => ConnectionScope.OpenConsumerLinkAsync(consumerGroup, partitionId, eventPosition, consumerOptions, timeout, CancellationToken.None), link => link.SafeClose());

            _retryPolicy = retryPolicy;
            _tryTimeout  = retryPolicy.CalculateTryTimeout(0);
        }
        /// <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);
            });
        }
Beispiel #10
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpClient"/> class.
        /// </summary>
        ///
        /// <param name="host">The fully qualified host name for the Event Hubs namespace.  This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param>
        /// <param name="eventHubName">The name of the specific Event Hub to connect the client to.</param>
        /// <param name="operationTimeout">The amount of time to allow for an AMQP operation using the link to complete before attempting to cancel it.</param>
        /// <param name="credential">The Azure managed identity credential to use for authorization.  Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param>
        /// <param name="clientOptions">A set of options to apply when configuring the client.</param>
        /// <param name="connectionScope">The optional scope to use for AMQP connection management.  If <c>null</c>, a new scope will be created.</param>
        /// <param name="messageConverter">The optional converter to use for transforming AMQP message-related types.  If <c>null</c>, a new converter will be created.</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>
        ///
        protected AmqpClient(string host,
                             string eventHubName,
                             TimeSpan operationTimeout,
                             EventHubTokenCredential credential,
                             EventHubConnectionOptions clientOptions,
                             AmqpConnectionScope connectionScope,
                             AmqpMessageConverter messageConverter)
        {
            Argument.AssertNotNullOrEmpty(host, nameof(host));
            Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName));
            Argument.AssertNotNegative(operationTimeout, nameof(operationTimeout));
            Argument.AssertNotNull(credential, nameof(credential));
            Argument.AssertNotNull(clientOptions, nameof(clientOptions));

            try
            {
                EventHubsEventSource.Log.EventHubClientCreateStart(host, eventHubName);

                ServiceEndpoint = new UriBuilder
                {
                    Scheme = clientOptions.TransportType.GetUriScheme(),
                    Host   = host
                }.Uri;

                ConnectionEndpoint = clientOptions.CustomEndpointAddress switch
                {
                    null => ServiceEndpoint,

                    _ => new UriBuilder
                    {
                        Scheme = ServiceEndpoint.Scheme,
                        Host   = clientOptions.CustomEndpointAddress.Host
                    }.Uri
                };

                EventHubName     = eventHubName;
                Credential       = credential;
                MessageConverter = messageConverter ?? new AmqpMessageConverter();

                ConnectionScope = connectionScope ?? new AmqpConnectionScope(
                    ServiceEndpoint,
                    ConnectionEndpoint,
                    eventHubName,
                    credential,
                    clientOptions.TransportType,
                    clientOptions.Proxy,
                    clientOptions.ConnectionIdleTimeout,
                    null,
                    clientOptions.SendBufferSizeInBytes,
                    clientOptions.ReceiveBufferSizeInBytes,
                    clientOptions.CertificateValidationCallback);

                ManagementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(
                    linkTimeout => ConnectionScope.OpenManagementLinkAsync(operationTimeout, linkTimeout, CancellationToken.None),
                    link =>
                {
                    link.Session?.SafeClose();
                    link.SafeClose();
                    EventHubsEventSource.Log.FaultTolerantAmqpObjectClose(nameof(RequestResponseAmqpLink), "", EventHubName, "", "", link.TerminalException?.Message);
                });
            }
            finally
            {
                EventHubsEventSource.Log.EventHubClientCreateComplete(host, eventHubName);
            }
        }