Пример #1
0
 public AmqpServiceClient(AmqpEventHubClient eventHubClient, string address)
     : base("AmqpServiceClient-" + StringUtility.GetRandomString())
 {
     this.eventHubClient = eventHubClient;
     Address             = address;
     link = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(OpenLinkAsync, rrlink => rrlink.CloseAsync(TimeSpan.FromSeconds(10)));
 }
Пример #2
0
        internal static async Task <AmqpResponseMessage> ExecuteRequestResponseAsync(
            AmqpConnectionScope connectionScope,
            FaultTolerantAmqpObject <RequestResponseAmqpLink> managementLink,
            AmqpRequestMessage amqpRequestMessage,
            string transactionGroup,
            TimeSpan timeout)
        {
            AmqpMessage amqpMessage = amqpRequestMessage.AmqpMessage;

            ArraySegment <byte> transactionId = AmqpConstants.NullBinary;
            var ambientTransaction            = Transaction.Current;

            if (ambientTransaction != null)
            {
                transactionId = await AmqpTransactionManager.Instance.EnlistAsync(
                    ambientTransaction,
                    connectionScope,
                    transactionGroup,
                    timeout)
                                .ConfigureAwait(false);
            }

            if (!managementLink.TryGetOpenedObject(out var requestResponseAmqpLink))
            {
                // MessagingEventSource.Log.CreatingNewLink(this.ClientId, this.isSessionReceiver, this.SessionIdInternal, true, this.LinkException);
                requestResponseAmqpLink = await managementLink.GetOrCreateAsync(timeout).ConfigureAwait(false);
            }

            var responseAmqpMessage = await Task.Factory.FromAsync(
                (c, s) => requestResponseAmqpLink.BeginRequest(amqpMessage, transactionId, timeout, c, s),
                (a) => requestResponseAmqpLink.EndRequest(a),
                null).ConfigureAwait(false);

            return(AmqpResponseMessage.CreateResponse(responseAmqpMessage));
        }
Пример #3
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="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();
            });
        }
Пример #4
0
 public IotHubConnection(IotHubConnectionString connectionString, AccessRights accessRights)
 {
     this.connectionString     = connectionString;
     this.accessRights         = accessRights;
     this.faultTolerantSession = new FaultTolerantAmqpObject <AmqpSession>(this.CreateSessionAsync, this.CloseConnection);
     this.refreshTokenTimer    = new IOThreadTimer(s => ((IotHubConnection)s).OnRefreshToken(), this, false);
 }
        internal static async Task DisposeMessageAsync(FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink, string lockToken, Outcome outcome, bool batchable)
        {
            var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken);

            Outcome disposeOutcome;

            try
            {
                ReceivingAmqpLink deviceBoundReceivingLink = await faultTolerantReceivingLink.GetReceivingLinkAsync().ConfigureAwait(false);

                disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable, IotHubConnection.DefaultOperationTimeout).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }

            if (disposeOutcome.DescriptorCode != Accepted.Code)
            {
                throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome);
            }
        }
Пример #6
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="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();
            });
        }
Пример #7
0
        ///// <summary>
        /////   The converter to use for translating between AMQP messages and client library
        /////   types.
        ///// </summary>
        //private AmqpMessageConverter MessageConverter { get; }

        ///// <summary>
        /////   The AMQP connection scope responsible for managing transport constructs for this instance.
        ///// </summary>
        /////
        //internal AmqpConnectionScope ConnectionScope { get; }

        ///// <summary>
        /////   The AMQP link intended for use with receiving operations.
        ///// </summary>
        /////
        //internal FaultTolerantAmqpObject<ReceivingAmqpLink> ReceiveLink { get; }

        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpConsumer"/> class.
        /// </summary>
        ///
        /// <param name="entityName">The name of the Service Bus entity from which events will be consumed.</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="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param>
        /// <param name="connectionScope">The AMQP connection context for operations .</param>
        /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param>
        /// <param name="sessionId"></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 entityName,
            long?ownerLevel,
            uint?prefetchCount,
            AmqpConnectionScope connectionScope,
            ServiceBusRetryPolicy retryPolicy,
            string sessionId)
        {
            Argument.AssertNotNullOrEmpty(entityName, nameof(entityName));
            Argument.AssertNotNull(connectionScope, nameof(connectionScope));
            Argument.AssertNotNull(retryPolicy, nameof(retryPolicy));
            EntityName      = entityName;
            ConnectionScope = connectionScope;
            RetryPolicy     = retryPolicy;

            ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(
                timeout =>
                ConnectionScope.OpenConsumerLinkAsync(
                    //consumerGroup,
                    //partitionId,
                    timeout,
                    prefetchCount ?? DefaultPrefetchCount,
                    ownerLevel,
                    sessionId,
                    CancellationToken.None),
                link =>
            {
                CloseLink(link);
            });
        }
Пример #8
0
        private async Task <Controller> GetController(TimeSpan timeout)
        {
            FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
            Controller controller = await faultTolerantController.GetOrCreateAsync(timeout).ConfigureAwait(false);

            return(controller);
        }
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpConnectionScope"/> class.
        /// </summary>
        ///
        /// <param name="serviceEndpoint">Endpoint for the Service Bus service to which the scope is associated.</param>
        /// <param name="credential">The credential to use for authorization with the Service Bus service.</param>
        /// <param name="transport">The transport to use for communication.</param>
        /// <param name="proxy">The proxy, if any, to use for communication.</param>
        /// <param name="identifier">The identifier to assign this scope; if not provided, one will be generated.</param>
        ///
        public AmqpConnectionScope(Uri serviceEndpoint,
                                   ServiceBusTokenCredential credential,
                                   ServiceBusTransportType transport,
                                   IWebProxy proxy,
                                   string identifier = default)
        {
            Argument.AssertNotNull(serviceEndpoint, nameof(serviceEndpoint));
            Argument.AssertNotNull(credential, nameof(credential));
            ValidateTransport(transport);

            ServiceEndpoint = serviceEndpoint;
            Transport       = transport;
            Proxy           = proxy;
            TokenProvider   = new CbsTokenProvider(new ServiceBusTokenCredential(credential, serviceEndpoint.ToString()), OperationCancellationSource.Token);
            Id = identifier ?? $"{ ServiceEndpoint }-{ Guid.NewGuid().ToString("D").Substring(0, 8) }";

            Task <AmqpConnection> connectionFactory(TimeSpan timeout) => CreateAndOpenConnectionAsync(AmqpVersion, ServiceEndpoint, Transport, Proxy, Id, timeout);

            ActiveConnection = new FaultTolerantAmqpObject <AmqpConnection>(
                connectionFactory,
                CloseConnection);
            TransactionController = new FaultTolerantAmqpObject <Controller>(
                CreateControllerAsync,
                CloseController);
        }
 public IotHubConnection(IotHubConnectionString connectionString, AccessRights accessRights)
 {
     this.connectionString = connectionString;
     this.accessRights = accessRights;
     this.faultTolerantSession = new FaultTolerantAmqpObject<AmqpSession>(this.CreateSessionAsync, this.CloseConnection);
     this.refreshTokenTimer = new IOThreadTimer(s => ((IotHubConnection)s).OnRefreshToken(), this, false);
 }
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpConnectionScope"/> class.
        /// </summary>
        ///
        /// <param name="serviceEndpoint">Endpoint for the Service Bus service to which the scope is associated.</param>
        /// <param name="credential">The credential to use for authorization with the Service Bus service.</param>
        /// <param name="transport">The transport to use for communication.</param>
        /// <param name="proxy">The proxy, if any, to use for communication.</param>
        /// <param name="identifier">The identifier to assign this scope; if not provided, one will be generated.</param>
        ///
        public AmqpConnectionScope(Uri serviceEndpoint,
                                   ServiceBusTokenCredential credential,
                                   ServiceBusTransportType transport,
                                   IWebProxy proxy,
                                   string identifier = default)
        {
            Argument.AssertNotNull(serviceEndpoint, nameof(serviceEndpoint));
            Argument.AssertNotNull(credential, nameof(credential));
            ValidateTransport(transport);

            ServiceEndpoint = serviceEndpoint;
            Transport       = transport;
            Proxy           = proxy;
            TokenProvider   = new CbsTokenProvider(new ServiceBusTokenCredential(credential, serviceEndpoint.ToString()), OperationCancellationSource.Token);
            Id = identifier ?? $"{ ServiceEndpoint }-{ Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture).Substring(0, 8) }";

#pragma warning disable CA2214 // Do not call overridable methods in constructors. This internal method is virtual for testing purposes.
            Task <AmqpConnection> connectionFactory(TimeSpan timeout) => CreateAndOpenConnectionAsync(AmqpVersion, ServiceEndpoint, Transport, Proxy, Id, timeout);

#pragma warning restore CA2214 // Do not call overridable methods in constructors
            ActiveConnection = new FaultTolerantAmqpObject <AmqpConnection>(
                connectionFactory,
                CloseConnection);
            TransactionController = new FaultTolerantAmqpObject <Controller>(
                CreateControllerAsync,
                CloseController);
        }
Пример #12
0
 protected void InitializeConnection(ServiceBusConnectionStringBuilder builder)
 {
     this.Endpoint          = new Uri(builder.Endpoint);
     this.NetCredential     = new System.Net.NetworkCredential(builder.Username, builder.Password);
     this.TransportType     = builder.TransportType;
     this.ConnectionManager = new FaultTolerantAmqpObject <AmqpConnection>(this.CreateConnectionAsync, CloseConnection);
 }
Пример #13
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpSender"/> class.
        /// </summary>
        ///
        /// <param name="entityPath">The name of the entity to which messages will be sent.</param>
        /// <param name="connectionScope">The AMQP connection context for operations.</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 AmqpSender(
            string entityPath,
            AmqpConnectionScope connectionScope,
            ServiceBusRetryPolicy retryPolicy)
        {
            Argument.AssertNotNullOrEmpty(entityPath, nameof(entityPath));
            Argument.AssertNotNull(connectionScope, nameof(connectionScope));
            Argument.AssertNotNull(retryPolicy, nameof(retryPolicy));

            _entityPath      = entityPath;
            _retryPolicy     = retryPolicy;
            _connectionScope = connectionScope;

            _sendLink = new FaultTolerantAmqpObject <SendingAmqpLink>(
                timeout => CreateLinkAndEnsureSenderStateAsync(timeout, CancellationToken.None),
                link =>
            {
                link.Session?.SafeClose();
                link.SafeClose();
            });

            _managementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(
                timeout => _connectionScope.OpenManagementLinkAsync(
                    _entityPath,
                    timeout,
                    CancellationToken.None),
                link =>
            {
                link.Session?.SafeClose();
                link.SafeClose();
            });
        }
        private async Task SinglePhaseCommitAsync(SinglePhaseEnlistment singlePhaseEnlistment)
        {
            try
            {
                FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
                Controller controller = await faultTolerantController.GetOrCreateAsync(_timeout)
                                        .ConfigureAwait(false);

                await controller.DischargeAsync(AmqpTransactionId, fail : false).ConfigureAwait(false);

                singlePhaseEnlistment.Committed();
                ServiceBusEventSource.Log.TransactionDischarged(
                    _transactionId,
                    AmqpTransactionId,
                    false);
                await CloseAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Exception exception = AmqpExceptionHelper.TranslateException(e, null);
                ServiceBusEventSource.Log.TransactionDischargeException(
                    _transactionId,
                    AmqpTransactionId,
                    exception);
                singlePhaseEnlistment.InDoubt(exception);
            }
        }
Пример #15
0
        public AmqpServiceClient(
            IotHubConnectionProperties connectionProperties,
            bool useWebSocketOnly,
            ServiceClientTransportSettings transportSettings,
            ServiceClientOptions options)
        {
            var iotHubConnection = new IotHubConnection(connectionProperties, useWebSocketOnly, transportSettings);

            Connection                = iotHubConnection;
            OpenTimeout               = IotHubConnection.DefaultOpenTimeout;
            OperationTimeout          = IotHubConnection.DefaultOperationTimeout;
            _faultTolerantSendingLink = new FaultTolerantAmqpObject <SendingAmqpLink>(CreateSendingLinkAsync, Connection.CloseLink);
            _feedbackReceiver         = new AmqpFeedbackReceiver(Connection);
            _fileNotificationReceiver = new AmqpFileNotificationReceiver(Connection);
            _iotHubName               = connectionProperties.IotHubName;
            _clientOptions            = options;
            _httpClientHelper         = new HttpClientHelper(
                connectionProperties.HttpsEndpoint,
                connectionProperties,
                ExceptionHandlingHelper.GetDefaultErrorMapping(),
                s_defaultOperationTimeout,
                transportSettings.HttpProxy,
                transportSettings.ConnectionLeaseTimeoutMilliseconds);

            // Set the trace provider for the AMQP library.
            AmqpTrace.Provider = new AmqpTransportLog();
        }
 protected void InitializeConnection(ServiceBusConnectionStringBuilder builder)
 {
     this.Endpoint          = new Uri(builder.Endpoint);
     this.SasKeyName        = builder.SasKeyName;
     this.SasKey            = builder.SasKey;
     this.ConnectionManager = new FaultTolerantAmqpObject <AmqpConnection>(this.CreateConnectionAsync, CloseConnection);
 }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AmqpRuleManager"/> class.
        /// </summary>
        ///
        /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param>
        /// <param name="connectionScope">The AMQP connection context for operations.</param>
        /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param>
        /// <param name="identifier">The identifier for the rule manager.</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 AmqpRuleManager(
            string subscriptionPath,
            AmqpConnectionScope connectionScope,
            ServiceBusRetryPolicy retryPolicy,
            string identifier)
        {
            Argument.AssertNotNullOrEmpty(subscriptionPath, nameof(subscriptionPath));
            Argument.AssertNotNull(connectionScope, nameof(connectionScope));
            Argument.AssertNotNull(retryPolicy, nameof(retryPolicy));

            _subscriptionPath = subscriptionPath;
            _connectionScope  = connectionScope;
            _retryPolicy      = retryPolicy;
            _identifier       = identifier;

            _managementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(
                timeout => _connectionScope.OpenManagementLinkAsync(
                    _subscriptionPath,
                    _identifier,
                    timeout,
                    CancellationToken.None),
                link =>
            {
                link.Session?.SafeClose();
                link.SafeClose();
            });
        }
Пример #18
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="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);
            }
        }
Пример #19
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpConsumer"/> class.
        /// </summary>
        ///
        /// <param name="entityName">The name of the Service Bus entity from which events will be consumed.</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="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param>
        /// <param name="connectionScope">The AMQP connection context for operations .</param>
        /// <param name="retryPolicy">The retry policy to consider when an operation fails.</param>
        /// <param name="sessionId"></param>
        /// <param name="isSessionReceiver"></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 entityName,
            ReceiveMode receiveMode,
            uint?prefetchCount,
            AmqpConnectionScope connectionScope,
            ServiceBusRetryPolicy retryPolicy,
            string sessionId,
            bool isSessionReceiver)
        {
            Argument.AssertNotNullOrEmpty(entityName, nameof(entityName));
            Argument.AssertNotNull(connectionScope, nameof(connectionScope));
            Argument.AssertNotNull(retryPolicy, nameof(retryPolicy));
            EntityName         = entityName;
            _connectionScope   = connectionScope;
            _retryPolicy       = retryPolicy;
            _isSessionReceiver = isSessionReceiver;
            _receiveMode       = receiveMode;

            ReceiveLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(
                timeout =>
                _connectionScope.OpenConsumerLinkAsync(
                    timeout: timeout,
                    prefetchCount: prefetchCount ?? DefaultPrefetchCount,
                    receiveMode: receiveMode,
                    sessionId: sessionId,
                    isSessionReceiver: isSessionReceiver,
                    cancellationToken: CancellationToken.None),
                link =>
            {
                CloseLink(link);
            });
        }
Пример #20
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpEventHubConsumer"/> 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 AmqpEventHubConsumer(string eventHubName,
                                    string consumerGroup,
                                    string partitionId,
                                    EventPosition eventPosition,
                                    EventHubConsumerOptions consumerOptions,
                                    AmqpConnectionScope connectionScope,
                                    AmqpMessageConverter messageConverter,
                                    EventHubRetryPolicy 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(EventHubConsumerOptions));
            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;
            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);
        }
 public AmqpFeedbackReceiver(IotHubConnection iotHubConnection)
 {
     this.iotHubConnection           = iotHubConnection;
     this.openTimeout                = IotHubConnection.DefaultOpenTimeout;
     this.operationTimeout           = IotHubConnection.DefaultOperationTimeout;
     this.receivingPath              = GetReceivingPath(EndpointKind.Feedback);
     this.faultTolerantReceivingLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateReceivingLinkAsync, this.iotHubConnection.CloseLink);
 }
Пример #22
0
 public AmqpFileNotificationReceiver(IotHubConnection iotHubConnection)
 {
     this.Connection                 = iotHubConnection;
     this.OpenTimeout                = IotHubConnection.DefaultOpenTimeout;
     this.OperationTimeout           = IotHubConnection.DefaultOperationTimeout;
     this.receivingPath              = AmqpClientHelper.GetReceivingPath(EndpointKind.FileNotification);
     this.faultTolerantReceivingLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(this.CreateReceivingLinkAsync, this.Connection.CloseLink);
 }
Пример #23
0
 public AmqpServiceClient(AmqpEventHubClient eventHubClient, string address)
     : base("AmqpServiceClient-" + StringUtility.GetRandomString())
 {
     this.eventHubClient    = eventHubClient;
     this.Address           = address;
     this.link              = new FaultTolerantAmqpObject <RequestResponseAmqpLink>(t => this.OpenLinkAsync(t), rrlink => rrlink.CloseAsync(TimeSpan.FromSeconds(10)));
     this.clientLinkManager = new ActiveClientLinkManager(this.eventHubClient);
 }
Пример #24
0
 internal AmqpServiceClient(IotHubConnection iotHubConnection, IHttpClientHelper httpClientHelper)
 {
     this.iotHubConnection         = iotHubConnection;
     this.faultTolerantSendingLink = new FaultTolerantAmqpObject <SendingAmqpLink>(this.CreateSendingLinkAsync, iotHubConnection.CloseLink);
     this.feedbackReceiver         = new AmqpFeedbackReceiver(iotHubConnection);
     this.fileNotificationReceiver = new AmqpFileNotificationReceiver(iotHubConnection);
     this.httpClientHelper         = httpClientHelper;
 }
Пример #25
0
 public AmqpFeedbackReceiver(IotHubConnection iotHubConnection)
 {
     Connection                  = iotHubConnection;
     OpenTimeout                 = IotHubConnection.DefaultOpenTimeout;
     OperationTimeout            = IotHubConnection.DefaultOperationTimeout;
     _receivingPath              = AmqpClientHelper.GetReceivingPath(EndpointKind.Feedback);
     _faultTolerantReceivingLink = new FaultTolerantAmqpObject <ReceivingAmqpLink>(CreateReceivingLinkAsync, Connection.CloseLink);
 }
Пример #26
0
 // internal test helper
 internal ServiceClient(IotHubConnection connection, IHttpClientHelper httpClientHelper)
 {
     Connection                = connection;
     _httpClientHelper         = httpClientHelper;
     _feedbackReceiver         = new AmqpFeedbackReceiver(Connection);
     _fileNotificationReceiver = new AmqpFileNotificationReceiver(Connection);
     _faultTolerantSendingLink = new FaultTolerantAmqpObject <SendingAmqpLink>(CreateSendingLinkAsync, Connection.CloseLink);
 }
Пример #27
0
 internal static async Task DisposeMessageAsync(
     FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink,
     string lockToken,
     Outcome outcome,
     bool batchable)
 {
     using var cts = new CancellationTokenSource(IotHubConnection.DefaultOperationTimeout);
     await DisposeMessageAsync(faultTolerantReceivingLink, lockToken, outcome, batchable, cts.Token).ConfigureAwait(false);
 }
Пример #28
0
        internal static async Task <ReceivingAmqpLink> GetReceivingLinkAsync(this FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink)
        {
            if (!faultTolerantReceivingLink.TryGetOpenedObject(out ReceivingAmqpLink receivingLink))
            {
                receivingLink = await faultTolerantReceivingLink.GetOrCreateAsync(IotHubConnection.DefaultOpenTimeout).ConfigureAwait(false);
            }

            return(receivingLink);
        }
 public AmqpDeviceClient(IotHubConnectionString connectionString, bool useWebSocketOnly)
 {
     this.IotHubConnection = connectionCache.GetConnection(connectionString, useWebSocketOnly);
     this.deviceId = connectionString.DeviceId;
     this.openTimeout = IotHubConnection.DefaultOpenTimeout;
     this.operationTimeout = IotHubConnection.DefaultOperationTimeout;
     this.DefaultReceiveTimeout = IotHubConnection.DefaultOperationTimeout;
     this.faultTolerantEventSendingLink = new FaultTolerantAmqpObject<SendingAmqpLink>(this.CreateEventSendingLinkAsync, this.IotHubConnection.CloseLink);
     this.faultTolerantDeviceBoundReceivingLink = new FaultTolerantAmqpObject<ReceivingAmqpLink>(this.CreateDeviceBoundReceivingLinkAsync, this.IotHubConnection.CloseLink);
 }
        /// <inheritdoc/>
        public void Dispose()
        {
            _faultTolerantSession?.Dispose();
            _faultTolerantSession = null;

            _refreshTokenTimer?.Dispose();
            _refreshTokenTimer = null;

            _clientWebSocketTransport?.Dispose();
            _clientWebSocketTransport = null;
        }
Пример #31
0
 public AmqpDeviceClient(IotHubConnectionString connectionString, AmqpTransportSettings transportSettings)
 {
     this.IotHubConnection = connectionCache.GetConnection(connectionString, transportSettings);
     this.deviceId = connectionString.DeviceId;
     this.openTimeout = IotHubConnection.DefaultOpenTimeout;
     this.operationTimeout = IotHubConnection.DefaultOperationTimeout;
     this.DefaultReceiveTimeout = IotHubConnection.DefaultOperationTimeout;
     this.faultTolerantEventSendingLink = new FaultTolerantAmqpObject<SendingAmqpLink>(this.CreateEventSendingLinkAsync, this.IotHubConnection.CloseLink);
     this.faultTolerantDeviceBoundReceivingLink = new FaultTolerantAmqpObject<ReceivingAmqpLink>(this.CreateDeviceBoundReceivingLinkAsync, this.IotHubConnection.CloseLink);
     this.prefetchCount = transportSettings.PrefetchCount;
 }
Пример #32
0
        internal AmqpEventDataSender(AmqpEventHubClient eventHubClient, string partitionId)
            : base(eventHubClient, partitionId)
        {
            Path = !string.IsNullOrEmpty(partitionId)
                ? $"{eventHubClient.EventHubName}/Partitions/{partitionId}"
                : eventHubClient.EventHubName;

            SendLinkManager    = new FaultTolerantAmqpObject <SendingAmqpLink>(CreateLinkAsync, CloseSession);
            _clientLinkManager = new ActiveClientLinkManager((AmqpEventHubClient)EventHubClient);
            MaxMessageSize     = 256 * 1024; // Default. Updated when link is opened
        }
Пример #33
0
        public void FaultTolerantAmqpObjectShouldInvokeCloseMethodOnClose()
        {
            bool isCloseHandlerInvoked = false;
            var  faultTolerantObject   = new FaultTolerantAmqpObject <TestAmqpObject>(
                span => Task.FromResult(new TestAmqpObject("string")),
                amqpObject => { isCloseHandlerInvoked = true; });
            var testAmqpObject = faultTolerantObject.GetOrCreateAsync(TimeSpan.FromSeconds(3)).Result;

            testAmqpObject.Close();
            Assert.True(isCloseHandlerInvoked);
        }
Пример #34
0
 public AmqpServiceClient(IotHubConnectionString iotHubConnectionString, bool useWebSocketOnly)
 {
     var iotHubConnection = new IotHubConnection(iotHubConnectionString, AccessRights.ServiceConnect, useWebSocketOnly);
     this.iotHubConnection = iotHubConnection;
     this.openTimeout = IotHubConnection.DefaultOpenTimeout;
     this.operationTimeout = IotHubConnection.DefaultOperationTimeout;
     this.sendingPath = "/messages/deviceBound";
     this.faultTolerantSendingLink = new FaultTolerantAmqpObject<SendingAmqpLink>(this.CreateSendingLinkAsync, this.iotHubConnection.CloseLink);
     this.feedbackReceiver = new AmqpFeedbackReceiver(this.iotHubConnection);
     this.iotHubName = iotHubConnectionString.IotHubName;
     this.httpClientHelper = new HttpClientHelper(
         iotHubConnectionString.HttpsEndpoint,
         iotHubConnectionString,
         ExceptionHandlingHelper.GetDefaultErrorMapping(),
         DefaultOperationTimeout,
         client => {});
 }