Пример #1
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));
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fromSequenceNumber"></param>
        /// <param name="maxMessages"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async IAsyncEnumerable <ServiceBusMessage> PeekRangeBySequenceInternal(
            long?fromSequenceNumber,
            int maxMessages = 1,
            [EnumeratorCancellation]
            CancellationToken cancellationToken = default)
        {
            RetriableContext  context    = CreateRetriableContext(cancellationToken);
            ReceivingAmqpLink openedLink =
                await context.RunOperation(
                    async() => await Consumer.ReceiveLink.GetOrCreateAsync(context.TimeSpan)
                    .ConfigureAwait(false))
                .ConfigureAwait(false);

            var source = (Source)openedLink.Settings.Source;

            if (source.FilterSet.TryGetValue <string>(AmqpClientConstants.SessionFilterName, out var tempSessionId))
            {
                // If one of the constructors not accepting a SessionId was used, the broker will determine which session to send messages from.
                SessionId = tempSessionId;
            }
            IAsyncEnumerable <ServiceBusMessage> ret = PeekRangeBySequenceInternal(
                fromSequenceNumber: fromSequenceNumber,
                maxMessages: maxMessages,
                sessionId: SessionId,
                cancellationToken: cancellationToken);

            await foreach (ServiceBusMessage msg in ret.ConfigureAwait(false))
            {
                yield return(msg);
            }
        }
Пример #3
0
        private async Task <IEnumerable <ServiceBusMessage> > PeekInternal(
            RetriableContext context,
            long?fromSequenceNumber,
            int messageCount       = 1,
            string sessionId       = null,
            string receiveLinkName = null)
        {
            AmqpRequestMessage amqpRequestMessage = AmqpRequestMessage.CreateRequest(
                ManagementConstants.Operations.PeekMessageOperation,
                context.TimeSpan,
                null);

            await AquireAccessTokenAsync(context.CancellationToken).ConfigureAwait(false);

            if (receiveLinkName != null)
            {
                // include associated link for service optimization
                amqpRequestMessage.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = receiveLinkName;
            }

            amqpRequestMessage.Map[ManagementConstants.Properties.FromSequenceNumber] = fromSequenceNumber ?? LastPeekedSequenceNumber + 1;
            amqpRequestMessage.Map[ManagementConstants.Properties.MessageCount]       = messageCount;

            if (!string.IsNullOrWhiteSpace(sessionId))
            {
                amqpRequestMessage.Map[ManagementConstants.Properties.SessionId] = sessionId;
            }

            RequestResponseAmqpLink link = await ManagementLink.GetOrCreateAsync(
                UseMinimum(ConnectionScope.SessionTimeout,
                           context.TimeSpan.CalculateRemaining(context.Stopwatch.Elapsed)))
                                           .ConfigureAwait(false);

            context.CancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

            // This is how Track 1 makes the request
            //var responseAmqpMessage = await Task.Factory.FromAsync(
            //(c, s) => link.BeginRequest(
            //    amqpRequestMessage.AmqpMessage,
            //    transactionId,
            //    TimeSpan.FromSeconds(30),
            //    c, s),
            //(a) => link.EndRequest(a),
            //this).ConfigureAwait(false);

            using AmqpMessage responseAmqpMessage = await link.RequestAsync(
                      amqpRequestMessage.AmqpMessage,
                      context.TimeSpan.CalculateRemaining(context.Stopwatch.Elapsed))
                                                    .ConfigureAwait(false);

            context.CancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

            AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(responseAmqpMessage);

            var messages = new List <ServiceBusMessage>();

            //AmqpError.ThrowIfErrorResponse(responseAmqpMessage, EntityName);
            if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
            {
                ServiceBusMessage     message     = null;
                IEnumerable <AmqpMap> messageList = amqpResponseMessage.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages);
                foreach (AmqpMap entry in messageList)
                {
                    var payload     = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message];
                    var amqpMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true);
                    message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, true);
                    messages.Add(message);
                }

                if (message != null)
                {
                    LastPeekedSequenceNumber = message.SystemProperties.SequenceNumber;
                }
                return(messages);
            }

            if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.NoContent ||
                (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.NotFound && Equals(AmqpClientConstants.MessageNotFoundError, amqpResponseMessage.GetResponseErrorCondition())))
            {
                return(messages);
            }
            // TODO throw correct exception
            throw new Exception();
        }