Example #1
0
 public override TransportReceiver CreateReceiver(string entityPath, ServiceBusRetryPolicy retryPolicy,
                                                  ServiceBusReceiveMode receiveMode, uint prefetchCount, string identifier, string sessionId, bool isSessionReceiver,
                                                  bool isProcessor,
                                                  CancellationToken cancellationToken)
 {
     throw new NotImplementedException();
 }
Example #2
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();
            });
        }
        /// <summary>
        ///   Creates a receiver strongly aligned with the active protocol and transport, responsible
        ///   for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity.
        /// </summary>
        /// <param name="entityPath">The entity path to receive from.</param>
        /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
        /// <param name="receiveMode">The <see cref="ServiceBusReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</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="identifier">The identifier for the sender.</param>
        /// <param name="sessionId">The session ID to receive messages for.</param>
        /// <param name="isSessionReceiver">Whether or not this is a sessionful receiver link.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the
        /// open link operation. Only applicable for session receivers.</param>
        ///
        /// <returns>A <see cref="TransportReceiver" /> configured in the requested manner.</returns>
        public override TransportReceiver CreateReceiver(
            string entityPath,
            ServiceBusRetryPolicy retryPolicy,
            ServiceBusReceiveMode receiveMode,
            uint prefetchCount,
            string identifier,
            string sessionId,
            bool isSessionReceiver,
            CancellationToken cancellationToken)
        {
            Argument.AssertNotDisposed(_closed, nameof(AmqpClient));

            return(new AmqpReceiver
                   (
                       entityPath,
                       receiveMode,
                       prefetchCount,
                       ConnectionScope,
                       retryPolicy,
                       identifier,
                       sessionId,
                       isSessionReceiver,
                       cancellationToken
                   ));
        }
 /// <summary>
 ///   Creates a consumer strongly aligned with the active protocol and transport, responsible
 ///   for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity.
 /// </summary>
 /// <param name="entityName"></param>
 ///
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</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="sessionId"></param>
 /// <param name="isSessionReceiver"></param>
 ///
 /// <returns>A <see cref="TransportReceiver" /> configured in the requested manner.</returns>
 ///
 public abstract TransportReceiver CreateReceiver(
     string entityName,
     ServiceBusRetryPolicy retryPolicy,
     ReceiveMode receiveMode,
     uint prefetchCount,
     string sessionId,
     bool isSessionReceiver);
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="retryPolicy"></param>
        /// <param name="fromSequenceNumber"></param>
        /// <param name="messageCount"></param>
        /// <param name="sessionId"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task <IEnumerable <ServiceBusMessage> > PeekAsync(
            ServiceBusRetryPolicy retryPolicy,
            long?fromSequenceNumber,
            int messageCount       = 1,
            string sessionId       = null,
            string receiveLinkName = null,
            CancellationToken cancellationToken = default)
        {
            IEnumerable <ServiceBusMessage> messages = null;
            Task peekTask = retryPolicy.RunOperation(async(timeout) =>
            {
                messages = await PeekInternal(
                    retryPolicy,
                    fromSequenceNumber,
                    messageCount,
                    sessionId,
                    receiveLinkName,
                    timeout,
                    cancellationToken).ConfigureAwait(false);
            },
                                                     EntityName,
                                                     ConnectionScope,
                                                     cancellationToken);
            await peekTask.ConfigureAwait(false);

            return(messages);
        }
        ///// <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);
            });
        }
Example #7
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);
            });
        }
Example #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="retryPolicy"></param>
        /// <param name="fromSequenceNumber"></param>
        /// <param name="messageCount"></param>
        /// <param name="sessionId"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task <IEnumerable <ServiceBusMessage> > PeekAsync(
            ServiceBusRetryPolicy retryPolicy,
            long?fromSequenceNumber,
            int messageCount       = 1,
            string sessionId       = null,
            string receiveLinkName = null,
            CancellationToken cancellationToken = default)
        {
            RetriableContext context = new RetriableContext(
                ConnectionScope,
                new Stopwatch(),
                retryPolicy,
                EntityName,
                cancellationToken);

            return(await context.RunOperation(
                       async() => await PeekInternal(
                           context,
                           fromSequenceNumber,
                           messageCount,
                           sessionId,
                           receiveLinkName)
                       .ConfigureAwait(false))
                   .ConfigureAwait(false));
        }
Example #9
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="retryPolicy"></param>
 /// <param name="fromSequenceNumber"></param>
 /// <param name="messageCount"></param>
 /// <param name="sessionId"></param>
 /// <param name="receiveLinkName"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public abstract Task <IEnumerable <ServiceBusMessage> > PeekAsync(
     ServiceBusRetryPolicy retryPolicy,
     long?fromSequenceNumber,
     int messageCount       = 1,
     string sessionId       = null,
     string receiveLinkName = null,
     CancellationToken cancellationToken = default);
        /// <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();
            });
        }
 public abstract TransportReceiver CreateReceiver(
     string entityPath,
     ServiceBusRetryPolicy retryPolicy,
     ServiceBusReceiveMode receiveMode,
     uint prefetchCount,
     string identifier,
     string sessionId,
     bool isSessionReceiver,
     string transactionGroup);
Example #12
0
 public abstract TransportReceiver CreateReceiver(string entityPath,
                                                  ServiceBusRetryPolicy retryPolicy,
                                                  ServiceBusReceiveMode receiveMode,
                                                  uint prefetchCount,
                                                  string identifier,
                                                  string sessionId,
                                                  bool isSessionReceiver,
                                                  bool isProcessor,
                                                  CancellationToken cancellationToken);
Example #13
0
        /// <summary>
        ///   Creates a producer strongly aligned with the active protocol and transport,
        ///   responsible for publishing <see cref="ServiceBusMessage" /> to the Service Bus entity.
        /// </summary>
        ///
        /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
        ///
        /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns>
        ///
        public override TransportSender CreateSender(ServiceBusRetryPolicy retryPolicy)
        {
            Argument.AssertNotClosed(_closed, nameof(AmqpClient));

            return(new AmqpSender
                   (
                       EntityName,
                       ConnectionScope,
                       retryPolicy
                   ));
        }
Example #14
0
        /// <summary>
        ///   Creates a rule manager strongly aligned with the active protocol and transport,
        ///   responsible for adding, removing and getting rules from the Service Bus subscription.
        /// </summary>
        ///
        /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param>
        /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
        ///
        /// <returns>A <see cref="TransportRuleManager"/> configured in the requested manner.</returns>
        public override TransportRuleManager CreateRuleManager(
            string subscriptionPath,
            ServiceBusRetryPolicy retryPolicy)
        {
            Argument.AssertNotClosed(_closed, nameof(AmqpClient));

            return(new AmqpRuleManager
                   (
                       subscriptionPath,
                       ConnectionScope,
                       retryPolicy
                   ));
        }
 public RetriableContext(
     AmqpConnectionScope scope,
     Stopwatch stopwatch,
     ServiceBusRetryPolicy retryPolicy,
     string entityName,
     CancellationToken cancellationToken)
 {
     Scope             = scope;
     Stopwatch         = stopwatch;
     RetryPolicy       = retryPolicy;
     TimeSpan          = retryPolicy.CalculateTryTimeout(0);
     CancellationToken = cancellationToken;
     EntityName        = entityName;
 }
        /// <summary>
        ///   Creates a producer strongly aligned with the active protocol and transport,
        ///   responsible for publishing <see cref="ServiceBusMessage" /> to the Service Bus entity.
        /// </summary>
        ///
        /// <param name="entityPath">The entity path to send the message to.</param>
        /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
        /// <param name="identifier">The identifier for the sender.</param>
        ///
        /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns>
        public override TransportSender CreateSender(
            string entityPath,
            ServiceBusRetryPolicy retryPolicy,
            string identifier)
        {
            Argument.AssertNotDisposed(_closed, nameof(AmqpClient));

            return(new AmqpSender
                   (
                       entityPath,
                       ConnectionScope,
                       retryPolicy,
                       identifier
                   ));
        }
Example #17
0
        /// <summary>
        ///   Creates a consumer strongly aligned with the active protocol and transport, responsible
        ///   for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity 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="retryPolicy">The policy which governs retry behavior and try timeouts.</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="sessionId"></param>
        ///
        /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns>
        ///
        public override TransportConsumer CreateConsumer(ServiceBusRetryPolicy retryPolicy,
                                                         long?ownerLevel,
                                                         uint?prefetchCount,
                                                         string sessionId = default)
        {
            Argument.AssertNotClosed(_closed, nameof(AmqpClient));

            return(new AmqpConsumer
                   (
                       EntityName,
                       ownerLevel,
                       prefetchCount,
                       ConnectionScope,
                       retryPolicy,
                       sessionId
                   ));
        }
Example #18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sequenceNumber"></param>
        /// <param name="retryPolicy"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="timeout"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task CancelScheduledMessageInternal(
            long sequenceNumber,
            ServiceBusRetryPolicy retryPolicy,
            string receiveLinkName,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            var stopWatch = Stopwatch.StartNew();

            var request = AmqpRequestMessage.CreateRequest(
                ManagementConstants.Operations.CancelScheduledMessageOperation,
                timeout,
                null);

            if (receiveLinkName != null)
            {
                request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName;
            }

            request.Map[ManagementConstants.Properties.SequenceNumbers] = new[] { sequenceNumber };

            RequestResponseAmqpLink link = await ManagementLink.GetOrCreateAsync(
                UseMinimum(ConnectionScope.SessionTimeout,
                           timeout.CalculateRemaining(stopWatch.Elapsed)))
                                           .ConfigureAwait(false);

            using AmqpMessage response = await link.RequestAsync(
                      request.AmqpMessage,
                      timeout.CalculateRemaining(stopWatch.Elapsed))
                                         .ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
            stopWatch.Stop();
            AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response);


            if (amqpResponseMessage.StatusCode != AmqpResponseStatusCode.OK)
            {
                throw new Exception();
                //throw response.ToMessagingContractException();
            }
            return;
        }
Example #19
0
        /// <summary>
        ///   Creates a consumer strongly aligned with the active protocol and transport, responsible
        ///   for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity.
        /// </summary>
        ///
        /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
        /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</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="sessionId"></param>
        /// <param name="isSessionReceiver"></param>
        ///
        /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns>
        ///
        public override TransportConsumer CreateConsumer(ServiceBusRetryPolicy retryPolicy,
                                                         ReceiveMode receiveMode,
                                                         uint?prefetchCount,
                                                         string sessionId,
                                                         bool isSessionReceiver)
        {
            Argument.AssertNotClosed(_closed, nameof(AmqpClient));

            return(new AmqpConsumer
                   (
                       EntityName,
                       receiveMode,
                       prefetchCount,
                       ConnectionScope,
                       retryPolicy,
                       sessionId,
                       isSessionReceiver
                   ));
        }
Example #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sequenceNumber"></param>
 /// <param name="retryPolicy"></param>
 /// <param name="receiveLinkName"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public override async Task CancelScheduledMessageAsync(
     long sequenceNumber,
     ServiceBusRetryPolicy retryPolicy,
     string receiveLinkName = null,
     CancellationToken cancellationToken = default)
 {
     Task cancelMessageTask = retryPolicy.RunOperation(async(timeout) =>
     {
         await CancelScheduledMessageInternal(
             sequenceNumber,
             retryPolicy,
             receiveLinkName,
             timeout,
             cancellationToken).ConfigureAwait(false);
     },
                                                       EntityName,
                                                       ConnectionScope,
                                                       cancellationToken);
     await cancelMessageTask.ConfigureAwait(false);
 }
Example #21
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="AmqpSender"/> class.
        /// </summary>
        ///
        /// <param name="entityName">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 entityName,
            AmqpConnectionScope connectionScope,
            ServiceBusRetryPolicy retryPolicy)
        {
            Argument.AssertNotNullOrEmpty(entityName, nameof(entityName));
            Argument.AssertNotNull(connectionScope, nameof(connectionScope));
            Argument.AssertNotNull(retryPolicy, nameof(retryPolicy));

            EntityName      = entityName;
            RetryPolicy     = retryPolicy;
            ConnectionScope = connectionScope;

            SendLink = new FaultTolerantAmqpObject <SendingAmqpLink>(
                timeout => CreateLinkAndEnsureProducerStateAsync(timeout, CancellationToken.None),
                link =>
            {
                link.Session?.SafeClose();
                link.SafeClose();
            });
        }
Example #22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="retryPolicy"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task <long> ScheduleMessageAsync(
            ServiceBusMessage message,
            ServiceBusRetryPolicy retryPolicy,
            string receiveLinkName = null,
            CancellationToken cancellationToken = default)
        {
            long sequenceNumber = 0;
            Task scheduleTask   = retryPolicy.RunOperation(async(timeout) =>
            {
                sequenceNumber = await ScheduleMessageInternal(
                    message,
                    retryPolicy,
                    receiveLinkName,
                    timeout,
                    cancellationToken).ConfigureAwait(false);
            },
                                                           EntityName,
                                                           ConnectionScope,
                                                           cancellationToken);
            await scheduleTask.ConfigureAwait(false);

            return(sequenceNumber);
        }
Example #23
0
 /// <summary>
 ///   Creates a consumer strongly aligned with the active protocol and transport, responsible
 ///   for reading <see cref="ServiceBusMessage" /> from a specific Service Bus entity.
 /// </summary>
 ///
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</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="sessionId"></param>
 /// <param name="isSessionReceiver"></param>
 ///
 /// <returns>A <see cref="TransportConsumer" /> configured in the requested manner.</returns>
 ///
 public abstract TransportConsumer CreateConsumer(
     ServiceBusRetryPolicy retryPolicy,
     ReceiveMode receiveMode,
     uint?prefetchCount,
     string sessionId,
     bool isSessionReceiver);
Example #24
0
 /// <summary>
 ///   Creates a rule manager strongly aligned with the active protocol and transport,
 ///   responsible for adding, removing and getting rules from the Service Bus subscription.
 /// </summary>
 ///
 /// <param name="subscriptionPath">The path of the Service Bus subscription to which the rule manager is bound.</param>
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 /// <param name="identifier">The identifier for the rule manager.</param>
 ///
 /// <returns>A <see cref="TransportRuleManager"/> configured in the requested manner.</returns>
 ///
 public abstract TransportRuleManager CreateRuleManager(
     string subscriptionPath,
     ServiceBusRetryPolicy retryPolicy,
     string identifier);
Example #25
0
 /// <summary>
 ///   Creates a sender strongly aligned with the active protocol and transport,
 ///   responsible for sending <see cref="ServiceBusMessage" /> to the entity.
 /// </summary>
 /// <param name="entityPath">The entity path to send the message to.</param>
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 /// <param name="identifier">The identifier for the sender.</param>
 ///
 /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns>
 ///
 public abstract TransportSender CreateSender(string entityPath, ServiceBusRetryPolicy retryPolicy, string identifier);
 /// <summary>
 ///   Creates a sender strongly aligned with the active protocol and transport,
 ///   responsible for sending <see cref="ServiceBusMessage" /> to the entity.
 /// </summary>
 /// <param name="entityPath">The entity path to send the message to.</param>
 /// <param name="viaEntityPath">The entity path to route the message through. Useful when using transactions.</param>
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 ///
 /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns>
 ///
 public abstract TransportSender CreateSender(string entityPath, string viaEntityPath, ServiceBusRetryPolicy retryPolicy);
Example #27
0
 /// <summary>
 ///   Creates a producer strongly aligned with the active protocol and transport,
 ///   responsible for publishing <see cref="ServiceBusMessage" /> to the entity.
 /// </summary>
 ///
 /// <param name="retryPolicy">The policy which governs retry behavior and try timeouts.</param>
 ///
 /// <returns>A <see cref="TransportSender"/> configured in the requested manner.</returns>
 ///
 public abstract TransportSender CreateSender(ServiceBusRetryPolicy retryPolicy);
Example #28
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="sequenceNumber"></param>
 /// <param name="retryPolicy"></param>
 /// <param name="receiveLinkName"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public abstract Task CancelScheduledMessageAsync(
     long sequenceNumber,
     ServiceBusRetryPolicy retryPolicy,
     string receiveLinkName = null,
     CancellationToken cancellationToken = default);
Example #29
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="message"></param>
 /// <param name="retryPolicy"></param>
 /// <param name="receiveLinkName"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public abstract Task <long> ScheduleMessageAsync(
     ServiceBusMessage message,
     ServiceBusRetryPolicy retryPolicy,
     string receiveLinkName = null,
     CancellationToken cancellationToken = default);
Example #30
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="retryPolicy"></param>
        /// <param name="receiveLinkName"></param>
        /// <param name="timeout"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task <long> ScheduleMessageInternal(
            ServiceBusMessage message,
            ServiceBusRetryPolicy retryPolicy,
            string receiveLinkName,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            var stopWatch = Stopwatch.StartNew();

            using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message))
            {
                var request = AmqpRequestMessage.CreateRequest(
                    ManagementConstants.Operations.ScheduleMessageOperation,
                    timeout,
                    null);

                if (receiveLinkName != null)
                {
                    request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName;
                }

                ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                var buffer = new BufferListStream(payload);
                ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length);

                var entry = new AmqpMap();
                {
                    entry[ManagementConstants.Properties.Message]   = value;
                    entry[ManagementConstants.Properties.MessageId] = message.MessageId;

                    if (!string.IsNullOrWhiteSpace(message.SessionId))
                    {
                        entry[ManagementConstants.Properties.SessionId] = message.SessionId;
                    }

                    if (!string.IsNullOrWhiteSpace(message.PartitionKey))
                    {
                        entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey;
                    }

                    if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey))
                    {
                        entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey;
                    }
                }

                request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                    entry
                };

                RequestResponseAmqpLink link = await ManagementLink.GetOrCreateAsync(
                    UseMinimum(ConnectionScope.SessionTimeout,
                               timeout.CalculateRemaining(stopWatch.Elapsed)))
                                               .ConfigureAwait(false);

                using AmqpMessage response = await link.RequestAsync(
                          request.AmqpMessage,
                          timeout.CalculateRemaining(stopWatch.Elapsed))
                                             .ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
                stopWatch.Stop();

                AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response);

                if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                {
                    var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                    if (sequenceNumbers == null || sequenceNumbers.Length < 1)
                    {
                        throw new ServiceBusException(true, "Could not schedule message successfully.");
                    }

                    return(sequenceNumbers[0]);
                }
                else
                {
                    throw new Exception();
                    //throw response.ToMessagingContractException();
                }
            }
        }