예제 #1
0
            static async Task <bool> ScheduleSend(SendEndpointContext clientContext, AzureServiceBusSendContext <T> context)
            {
                var now = DateTime.UtcNow;

                var enqueueTimeUtc = context.ScheduledEnqueueTimeUtc.Value;

                if (enqueueTimeUtc < now)
                {
                    LogContext.Debug?.Log("The scheduled time was in the past, sending: {ScheduledTime}", context.ScheduledEnqueueTimeUtc);

                    return(false);
                }

                try
                {
                    var brokeredMessage = CreateBrokeredMessage(context);

                    var sequenceNumber = await clientContext.ScheduleSend(brokeredMessage, enqueueTimeUtc).ConfigureAwait(false);

                    context.SetScheduledMessageId(sequenceNumber);

                    context.LogScheduled(enqueueTimeUtc);

                    return(true);
                }
                catch (ArgumentOutOfRangeException)
                {
                    LogContext.Debug?.Log("The scheduled time was rejected by the server, sending: {MessageId}", context.MessageId);

                    return(false);
                }
            }
            static void AddTransportHeaders(StartedActivity?startedActivity, AzureServiceBusSendContext <T> context)
            {
                if (!startedActivity.HasValue)
                {
                    return;
                }

                var activity = startedActivity.Value;

                activity.AddTag(nameof(context.PartitionKey), context.PartitionKey);
                activity.AddTag(nameof(context.SessionId), context.SessionId);
            }
예제 #3
0
            bool IsCancelScheduledSend(AzureServiceBusSendContext <T> context, out long sequenceNumber)
            {
                if (_message is CancelScheduledMessage cancelScheduledMessage)
                {
                    if (context.TryGetScheduledMessageId(out sequenceNumber) ||
                        context.TryGetSequenceNumber(cancelScheduledMessage.TokenId, out sequenceNumber))
                    {
                        return(true);
                    }
                }

                sequenceNumber = default;
                return(false);
            }
예제 #4
0
        Message CreateBrokeredMessage <T>(AzureServiceBusSendContext <T> context)
            where T : class
        {
            var brokeredMessage = new Message(context.Body)
            {
                ContentType = context.ContentType.MediaType
            };

            brokeredMessage.UserProperties.SetTextHeaders(context.Headers, (_, text) => text);

            if (context.TimeToLive.HasValue)
            {
                brokeredMessage.TimeToLive = context.TimeToLive.Value;
            }

            if (context.MessageId.HasValue)
            {
                brokeredMessage.MessageId = context.MessageId.Value.ToString("N");
            }

            if (context.CorrelationId.HasValue)
            {
                brokeredMessage.CorrelationId = context.CorrelationId.Value.ToString("N");
            }

            CopyIncomingIdentifiersIfPresent(context);
            if (context.PartitionKey != null)
            {
                brokeredMessage.PartitionKey = context.PartitionKey;
            }

            var sessionId = string.IsNullOrWhiteSpace(context.SessionId) ? context.ConversationId?.ToString("N") : context.SessionId;

            if (!string.IsNullOrWhiteSpace(sessionId))
            {
                brokeredMessage.SessionId = sessionId;

                if (context.ReplyToSessionId == null)
                {
                    brokeredMessage.ReplyToSessionId = sessionId;
                }
            }

            if (context.ReplyToSessionId != null)
            {
                brokeredMessage.ReplyToSessionId = context.ReplyToSessionId;
            }

            return(brokeredMessage);
        }
예제 #5
0
            static BrokeredMessage CreateBrokeredMessage(AzureServiceBusSendContext <T> context)
            {
                var brokeredMessage = new BrokeredMessage(context.GetBodyStream())
                {
                    ContentType      = context.ContentType.MediaType,
                    ForcePersistence = context.Durable
                };

                brokeredMessage.Properties.SetTextHeaders(context.Headers, (_, text) => text);

                if (context.TimeToLive.HasValue)
                {
                    brokeredMessage.TimeToLive = context.TimeToLive.Value;
                }

                if (context.MessageId.HasValue)
                {
                    brokeredMessage.MessageId = context.MessageId.Value.ToString("N");
                }

                if (context.CorrelationId.HasValue)
                {
                    brokeredMessage.CorrelationId = context.CorrelationId.Value.ToString("N");
                }

                if (context.PartitionKey != null)
                {
                    brokeredMessage.PartitionKey = context.PartitionKey;
                }

                var sessionId = string.IsNullOrWhiteSpace(context.SessionId) ? context.ConversationId?.ToString("N") : context.SessionId;

                if (!string.IsNullOrWhiteSpace(sessionId))
                {
                    brokeredMessage.SessionId = sessionId;

                    if (context.ReplyToSessionId == null)
                    {
                        brokeredMessage.ReplyToSessionId = sessionId;
                    }
                }

                if (context.ReplyToSessionId != null)
                {
                    brokeredMessage.ReplyToSessionId = context.ReplyToSessionId;
                }

                return(brokeredMessage);
            }
예제 #6
0
            static Message CreateBrokeredMessage(AzureServiceBusSendContext <T> context)
            {
                var brokeredMessage = new Message(context.Body)
                {
                    ContentType = context.ContentType.MediaType
                };

                brokeredMessage.UserProperties.Set(context.Headers);

                if (context.TimeToLive.HasValue)
                {
                    brokeredMessage.TimeToLive = context.TimeToLive > TimeSpan.Zero ? context.TimeToLive.Value : TimeSpan.FromSeconds(1);
                }

                if (context.MessageId.HasValue)
                {
                    brokeredMessage.MessageId = context.MessageId.Value.ToString("N");
                }

                if (context.CorrelationId.HasValue)
                {
                    brokeredMessage.CorrelationId = context.CorrelationId.Value.ToString("N");
                }

                if (context.PartitionKey != null)
                {
                    brokeredMessage.PartitionKey = context.PartitionKey;
                }

                if (!string.IsNullOrWhiteSpace(context.SessionId))
                {
                    brokeredMessage.SessionId = context.SessionId;

                    if (context.ReplyToSessionId == null)
                    {
                        brokeredMessage.ReplyToSessionId = context.SessionId;
                    }
                }

                if (context.ReplyToSessionId != null)
                {
                    brokeredMessage.ReplyToSessionId = context.ReplyToSessionId;
                }

                return(brokeredMessage);
            }
        public ConsumeContext Deserialize(ReceiveContext receiveContext)
        {
            var body                  = Encoding.UTF8.GetString(receiveContext.GetBody());
            var customMessage         = JsonConvert.DeserializeObject <CustomMessage>(body);
            var serviceBusSendContext = new AzureServiceBusSendContext <CustomMessage>(customMessage, CancellationToken.None);

            string[] messageTypes      = { "urn:message:MassTransitSample:CustomMessage" };
            var      serviceBusContext = receiveContext as ServiceBusReceiveContext;

            serviceBusSendContext.ContentType   = new ContentType(JsonMessageSerializer.JsonContentType.ToString());
            serviceBusSendContext.SourceAddress = serviceBusContext.InputAddress;
            serviceBusSendContext.SessionId     = serviceBusContext.SessionId;

            // sending JToken because we are using default Newtonsoft deserializer/serializer
            var messageEnv = new JsonMessageEnvelope(serviceBusSendContext, JObject.Parse(body), messageTypes);

            return(new JsonConsumeContext(JsonSerializer.CreateDefault(), receiveContext, messageEnv));
        }
예제 #8
0
            public async Task Send(SendEndpointContext clientContext)
            {
                var context = new AzureServiceBusSendContext <T>(_message, _cancellationToken);

                try
                {
                    await _pipe.Send(context).ConfigureAwait(false);

                    CopyIncomingIdentifiersIfPresent(context);

                    if (IsCancelScheduledSend(context, out var sequenceNumber))
                    {
                        await CancelScheduledSend(clientContext, sequenceNumber).ConfigureAwait(false);

                        return;
                    }

                    if (context.ScheduledEnqueueTimeUtc.HasValue)
                    {
                        var scheduled = await ScheduleSend(clientContext, context).ConfigureAwait(false);

                        if (scheduled)
                        {
                            return;
                        }
                    }

                    await _observer.PreSend(context).ConfigureAwait(false);

                    var brokeredMessage = CreateBrokeredMessage(context);

                    await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                    context.LogSent();

                    await _observer.PostSend(context).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    await _observer.SendFault(context, ex).ConfigureAwait(false);

                    throw;
                }
            }
        public async Task Should_create_the_brokered_message_receiver()
        {
            var message = new Mock <Message>();

            message.Object.ContentType = JsonMessageSerializer.ContentTypeHeaderValue;
            message.Object.MessageId   = NewId.NextGuid().ToString();

            using (var stream = new MemoryStream())
            {
                ServiceBusSendContext <PingMessage> context = new AzureServiceBusSendContext <PingMessage>(new PingMessage(), CancellationToken.None);

                var envelope = new JsonMessageEnvelope(context, context.Message, TypeMetadataCache <PingMessage> .MessageTypeNames);

                using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
                    using (var jsonWriter = new JsonTextWriter(writer))
                    {
                        jsonWriter.Formatting = Formatting.Indented;

                        JsonMessageSerializer.Serializer.Serialize(jsonWriter, envelope, typeof(MessageEnvelope));

                        jsonWriter.Flush();
                        writer.Flush();
                    }

                message.Object.Body = stream.ToArray();
            }

            var binder = new Mock <IBinder>();

            LogContext.ConfigureCurrentLogContext();

            var handler = Bus.Factory.CreateBrokeredMessageReceiver(binder.Object, LogContext.Current.Logger, cfg =>
            {
                cfg.InputAddress = new Uri("sb://masstransit-build.servicebus.windows.net/input-queue");

                cfg.UseRetry(x => x.Intervals(10, 100, 500, 1000));
                cfg.Consumer(() => new Consumer());
            });

            Console.WriteLine(handler.GetProbeResult().ToJsonString());

            //            await handler.Handle(message.Object);
        }
        public ConsumeContext Deserialize(ReceiveContext receiveContext)
        {
            var body                  = Encoding.UTF8.GetString(receiveContext.GetBody());
            var customMessage         = JsonConvert.DeserializeObject <EventGridEvent>(body);
            var serviceBusSendContext = new AzureServiceBusSendContext <EventGridEvent>(customMessage, CancellationToken.None);

            // this is the default scheme, that has to match in order messages to be processed
            // EventGrid messages type of EventGridEvent within namespace Microsoft.Azure.EventGrid.Models
            string[] messageTypes      = { "urn:message:Microsoft.Azure.EventGrid.Models:EventGridEvent" };
            var      serviceBusContext = receiveContext as ServiceBusReceiveContext;

            serviceBusSendContext.ContentType   = new ContentType(JsonMessageSerializer.JsonContentType.ToString());
            serviceBusSendContext.SourceAddress = serviceBusContext.InputAddress;
            serviceBusSendContext.SessionId     = serviceBusContext.SessionId;

            // sending JToken because we are using default Newtonsoft deserializer/serializer
            var messageEnv = new JsonMessageEnvelope(serviceBusSendContext, JObject.Parse(body), messageTypes);

            return(new JsonConsumeContext(JsonSerializer.CreateDefault(), receiveContext, messageEnv));
        }
예제 #11
0
            static void CopyIncomingIdentifiersIfPresent(AzureServiceBusSendContext <T> context)
            {
                if (context.TryGetPayload <ConsumeContext>(out var consumeContext) &&
                    consumeContext.TryGetPayload <BrokeredMessageContext>(out var brokeredMessageContext))
                {
                    if (context.SessionId == null)
                    {
                        if (brokeredMessageContext.ReplyToSessionId != null)
                        {
                            context.SessionId = brokeredMessageContext.ReplyToSessionId;
                        }
                        else if (brokeredMessageContext.SessionId != null)
                        {
                            context.SessionId = brokeredMessageContext.SessionId;
                        }
                    }

                    if (context.PartitionKey == null && brokeredMessageContext.PartitionKey != null)
                    {
                        context.PartitionKey = brokeredMessageContext.PartitionKey;
                    }
                }
            }
        void CopyIncomingIdentifiersIfPresent <T>(AzureServiceBusSendContext <T> sendContext)
            where T : class
        {
            if (sendContext.TryGetPayload <ConsumeContext>(out var consumeContext))
            {
                if (consumeContext.TryGetPayload <BrokeredMessageContext>(out var brokeredMessageContext))
                {
                    if (sendContext.SessionId == null && brokeredMessageContext.ReplyToSessionId != null)
                    {
                        sendContext.SessionId = brokeredMessageContext.ReplyToSessionId;
                    }

                    if (sendContext.SessionId == null && brokeredMessageContext.SessionId != null)
                    {
                        sendContext.SessionId = brokeredMessageContext.SessionId;
                    }

                    if (sendContext.PartitionKey == null && brokeredMessageContext.PartitionKey != null)
                    {
                        sendContext.PartitionKey = brokeredMessageContext.PartitionKey;
                    }
                }
            }
        }
예제 #13
0
            public async Task Send(SendEndpointContext clientContext)
            {
                LogContext.SetCurrentIfNull(_context.LogContext);

                var context = new AzureServiceBusSendContext <T>(_message, _cancellationToken);

                await _pipe.Send(context).ConfigureAwait(false);

                CopyIncomingIdentifiersIfPresent(context);

                StartedActivity?activity = LogContext.IfEnabled(OperationName.Transport.Send)?.StartSendActivity(context,
                                                                                                                 (nameof(context.PartitionKey), context.PartitionKey),
                                                                                                                 (nameof(context.SessionId), context.SessionId));

                try
                {
                    if (IsCancelScheduledSend(context, out var sequenceNumber))
                    {
                        await CancelScheduledSend(clientContext, sequenceNumber).ConfigureAwait(false);

                        return;
                    }

                    if (context.ScheduledEnqueueTimeUtc.HasValue)
                    {
                        var scheduled = await ScheduleSend(clientContext, context).ConfigureAwait(false);

                        if (scheduled)
                        {
                            return;
                        }
                    }

                    if (_context.SendObservers.Count > 0)
                    {
                        await _context.SendObservers.PreSend(context).ConfigureAwait(false);
                    }

                    var brokeredMessage = CreateBrokeredMessage(context);

                    await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                    context.LogSent();

                    if (_context.SendObservers.Count > 0)
                    {
                        await _context.SendObservers.PostSend(context).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    if (_context.SendObservers.Count > 0)
                    {
                        await _context.SendObservers.SendFault(context, ex).ConfigureAwait(false);
                    }

                    throw;
                }
                finally
                {
                    activity?.Stop();
                }
            }
        Task ISendTransport.Send <T>(T message, IPipe <SendContext <T> > pipe, CancellationToken cancellationToken)
        {
            IPipe <SendEndpointContext> clientPipe = Pipe.ExecuteAsync <SendEndpointContext>(async clientContext =>
            {
                var context = new AzureServiceBusSendContext <T>(message, cancellationToken);

                try
                {
                    await pipe.Send(context).ConfigureAwait(false);

                    if (message is CancelScheduledMessage cancelScheduledMessage &&
                        (context.TryGetScheduledMessageId(out var sequenceNumber) || context.TryGetSequencyNumber(cancelScheduledMessage.TokenId, out sequenceNumber)))
                    {
                        try
                        {
                            await clientContext.CancelScheduledSend(sequenceNumber).ConfigureAwait(false);

                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("Canceled Scheduled: {0} {1}", sequenceNumber, clientContext.EntityPath);
                            }
                        }
                        catch (MessageNotFoundException exception)
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("The scheduled message was not found: {0}", exception.Message);
                            }
                        }

                        return;
                    }

                    await _observers.PreSend(context).ConfigureAwait(false);

                    var brokeredMessage = new Message(context.Body)
                    {
                        ContentType = context.ContentType.MediaType
                    };

                    brokeredMessage.UserProperties.SetTextHeaders(context.Headers, (_, text) => text);

                    if (context.TimeToLive.HasValue)
                    {
                        brokeredMessage.TimeToLive = context.TimeToLive.Value;
                    }
                    if (context.MessageId.HasValue)
                    {
                        brokeredMessage.MessageId = context.MessageId.Value.ToString("N");
                    }
                    if (context.CorrelationId.HasValue)
                    {
                        brokeredMessage.CorrelationId = context.CorrelationId.Value.ToString("N");
                    }
                    CopyIncomingIdentifiersIfPresent(context);
                    if (context.PartitionKey != null)
                    {
                        brokeredMessage.PartitionKey = context.PartitionKey;
                    }
                    var sessionId = string.IsNullOrWhiteSpace(context.SessionId) ? context.ConversationId?.ToString("N") : context.SessionId;
                    if (!string.IsNullOrWhiteSpace(sessionId))
                    {
                        brokeredMessage.SessionId = sessionId;

                        if (context.ReplyToSessionId == null)
                        {
                            brokeredMessage.ReplyToSessionId = sessionId;
                        }
                    }
                    if (context.ReplyToSessionId != null)
                    {
                        brokeredMessage.ReplyToSessionId = context.ReplyToSessionId;
                    }
                    if (context.ScheduledEnqueueTimeUtc.HasValue)
                    {
                        var enqueueTimeUtc = context.ScheduledEnqueueTimeUtc.Value;

                        sequenceNumber = await clientContext.ScheduleSend(brokeredMessage, enqueueTimeUtc).ConfigureAwait(false);

                        context.SetScheduledMessageId(sequenceNumber);

                        context.LogScheduled(enqueueTimeUtc);
                    }
                    else
                    {
                        await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                        context.LogSent();

                        await _observers.PostSend(context).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await _observers.SendFault(context, ex).ConfigureAwait(false);

                    throw;
                }
            });

            return(_source.Send(clientPipe, cancellationToken));
        }
예제 #15
0
        Task ISendTransport.Send <T>(T message, IPipe <SendContext <T> > pipe, CancellationToken cancellationToken)
        {
            IPipe <SendEndpointContext> clientPipe = Pipe.ExecuteAsync <SendEndpointContext>(async clientContext =>
            {
                var context = new AzureServiceBusSendContext <T>(message, cancellationToken);

                try
                {
                    await pipe.Send(context).ConfigureAwait(false);

                    if (message is CancelScheduledMessage cancelScheduledMessage &&
                        (context.TryGetScheduledMessageId(out var sequenceNumber) ||
                         context.TryGetSequencyNumber(cancelScheduledMessage.TokenId, out sequenceNumber)))
                    {
                        try
                        {
                            await clientContext.CancelScheduledSend(sequenceNumber).ConfigureAwait(false);

                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("Canceled Scheduled: {0} {1}", sequenceNumber, clientContext.EntityPath);
                            }
                        }
                        catch (MessageNotFoundException exception)
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("The scheduled message was not found: {0}", exception.Message);
                            }
                        }

                        return;
                    }

                    await _observers.PreSend(context).ConfigureAwait(false);

                    var brokeredMessage = CreateBrokeredMessage(context);

                    if (context.ScheduledEnqueueTimeUtc.HasValue && context.ScheduledEnqueueTimeUtc.Value < DateTime.UtcNow)
                    {
                        var enqueueTimeUtc = context.ScheduledEnqueueTimeUtc.Value;

                        try
                        {
                            sequenceNumber = await clientContext.ScheduleSend(brokeredMessage, enqueueTimeUtc).ConfigureAwait(false);
                        }
                        catch (ArgumentOutOfRangeException exception)
                        {
                            brokeredMessage = CreateBrokeredMessage(context);

                            await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                            sequenceNumber = 0;
                        }

                        context.SetScheduledMessageId(sequenceNumber);

                        context.LogScheduled(enqueueTimeUtc);
                    }
                    else
                    {
                        await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                        context.LogSent();

                        await _observers.PostSend(context).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    await _observers.SendFault(context, ex).ConfigureAwait(false);

                    throw;
                }
            });

            return(_source.Send(clientPipe, cancellationToken));
        }
예제 #16
0
        Task ISendTransport.Send <T>(T message, IPipe <SendContext <T> > pipe, CancellationToken cancellationToken)
        {
            IPipe <SendEndpointContext> clientPipe = Pipe.ExecuteAsync <SendEndpointContext>(async clientContext =>
            {
                var context = new AzureServiceBusSendContext <T>(message, cancellationToken);

                try
                {
                    await pipe.Send(context).ConfigureAwait(false);

                    if (message is CancelScheduledMessage cancelScheduledMessage &&
                        (context.TryGetScheduledMessageId(out var sequenceNumber) || context.TryGetSequencyNumber(cancelScheduledMessage.TokenId, out sequenceNumber)))
                    {
                        try
                        {
                            await clientContext.CancelScheduledSend(sequenceNumber).ConfigureAwait(false);

                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("Canceled Scheduled: {0} {1}", sequenceNumber, clientContext.EntityPath);
                            }
                        }
                        catch (MessageNotFoundException exception)
                        {
                            if (_log.IsDebugEnabled)
                            {
                                _log.DebugFormat("The scheduled message was not found: {0}", exception.Detail.Message);
                            }
                        }

                        return;
                    }

                    await _observers.PreSend(context).ConfigureAwait(false);

                    using (var messageBodyStream = context.GetBodyStream())
                        using (var brokeredMessage = new BrokeredMessage(messageBodyStream))
                        {
                            brokeredMessage.ContentType      = context.ContentType.MediaType;
                            brokeredMessage.ForcePersistence = context.Durable;

                            KeyValuePair <string, object>[] headers = context.Headers.GetAll()
                                                                      .Where(x => x.Value != null && (x.Value is string || x.Value.GetType().IsValueType))
                                                                      .ToArray();

                            foreach (KeyValuePair <string, object> header in headers)
                            {
                                if (brokeredMessage.Properties.ContainsKey(header.Key))
                                {
                                    continue;
                                }

                                brokeredMessage.Properties.Add(header.Key, header.Value);
                            }

                            if (context.TimeToLive.HasValue)
                            {
                                brokeredMessage.TimeToLive = context.TimeToLive.Value;
                            }

                            if (context.MessageId.HasValue)
                            {
                                brokeredMessage.MessageId = context.MessageId.Value.ToString("N");
                            }

                            if (context.CorrelationId.HasValue)
                            {
                                brokeredMessage.CorrelationId = context.CorrelationId.Value.ToString("N");
                            }

                            CopyIncomingIdentifiersIfPresent(context);

                            if (context.PartitionKey != null)
                            {
                                brokeredMessage.PartitionKey = context.PartitionKey;
                            }

                            var sessionId = string.IsNullOrWhiteSpace(context.SessionId) ? context.ConversationId?.ToString("N") : context.SessionId;
                            if (!string.IsNullOrWhiteSpace(sessionId))
                            {
                                brokeredMessage.SessionId = sessionId;

                                if (context.ReplyToSessionId == null)
                                {
                                    brokeredMessage.ReplyToSessionId = sessionId;
                                }
                            }

                            if (context.ReplyToSessionId != null)
                            {
                                brokeredMessage.ReplyToSessionId = context.ReplyToSessionId;
                            }

                            if (context.ScheduledEnqueueTimeUtc.HasValue)
                            {
                                var enqueueTimeUtc = context.ScheduledEnqueueTimeUtc.Value;

                                sequenceNumber = await clientContext.ScheduleSend(brokeredMessage, enqueueTimeUtc).ConfigureAwait(false);

                                context.SetScheduledMessageId(sequenceNumber);

                                context.LogScheduled(enqueueTimeUtc);
                            }
                            else
                            {
                                await clientContext.Send(brokeredMessage).ConfigureAwait(false);

                                context.LogSent();

                                await _observers.PostSend(context).ConfigureAwait(false);
                            }
                        }
                }
                catch (Exception ex)
                {
                    await _observers.SendFault(context, ex).ConfigureAwait(false);

                    throw;
                }
            });

            return(_source.Send(clientPipe, cancellationToken));
        }