예제 #1
0
        public Task PublishAsync <T>(T message, MessagingPublisherOptions options = null,
                                     CancellationToken cancellationToken          = default)
        {
            options ??= MessagingPublisherOptions.Default;

            void NewCustomizer(MessagingEnvelope outgoingEnvelope)
            {
                if (_tracer.ActiveSpan != null)
                {
                    _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.TextMap,
                                   new TextMapInjectAdapter(outgoingEnvelope.Headers));
                }

                options.EnvelopeCustomizer?.Invoke(outgoingEnvelope);
            }

            var formattedTopicName = _topicRegistry.GetTopicForName(options.TopicName) ??
                                     _topicRegistry.GetTopicForMessageType(message.GetType());
            var operationName = $"Publisher {message.GetType().GetPrettyName()}";

            using (var scope = _tracer.BuildSpan(operationName)
                               .WithTag(Tags.Component, MessagingTags.ComponentMessaging)
                               .WithTag(Tags.SpanKind, Tags.SpanKindProducer)
                               .WithTag(Tags.MessageBusDestination, formattedTopicName)
                               .WithTag(MessagingTags.CorrelationId, CorrelationManager.GetCorrelationId()?.ToString())
                               .StartActive(true))
            {
                try
                {
                    return(_inner.PublishAsync(message, options with {
                        EnvelopeCustomizer = NewCustomizer
                    },
                                               cancellationToken));
                }
예제 #2
0
        public Task PublishAsync <T>(T message, CancellationToken cancellationToken = default, Action <MessagingEnvelope> customizer = null, string topicName = null)
        {
            void NewCustomizer(MessagingEnvelope outgoingEnvelope)
            {
                if (_tracer.ActiveSpan != null)
                {
                    _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.TextMap,
                                   new TextMapInjectAdapter(outgoingEnvelope.Headers));
                }

                customizer?.Invoke(outgoingEnvelope);
            }

            var formattedTopicName = _topicRegistry.GetTopicForName(topicName) ??
                                     _topicRegistry.GetTopicForMessageType(message.GetType());
            var operationName = $"Publisher {message.GetType().GetPrettyName()}";

            using (var scope = _tracer.BuildSpan(operationName)
                               .WithTag(Tags.Component, MessagingTags.ComponentMessaging)
                               .WithTag(Tags.SpanKind, Tags.SpanKindProducer)
                               .WithTag(Tags.MessageBusDestination, formattedTopicName)
                               .WithTag(MessagingTags.CorrelationId, CorrelationManager.GetCorrelationId()?.ToString())
                               .StartActive(true))
            {
                try
                {
                    return(_inner.PublishAsync(message, cancellationToken, NewCustomizer, topicName));
                }
                catch (Exception exception)
                {
                    scope.Span.SetException(exception);
                    throw;
                }
            }
        }
예제 #3
0
        public async Task <IDisposable> SubscribeAsync <TMessage>(Func <MessagingEnvelope <TMessage>, Task> handler,
                                                                  MessagingSubscriberOptions options  = null,
                                                                  CancellationToken cancellationToken = default)
        {
            var topicName = _topicRegistry.GetTopicForName(options?.TopicName) ??
                            _topicRegistry.GetTopicForMessageType(typeof(TMessage));

            async Task MsgHandler(byte[] messageData)
            {
                _logger.LogDebug("Messaging subscriber received message from subject {Subject}", topicName);

                try
                {
                    var messageEnvelope = _messageSerDes.DeserializeMessageEnvelope <TMessage>(messageData);

                    await handler(messageEnvelope);
                }
                catch (Exception ex)
                {
                    _logger.LogError(
                        "Messaging consumer encountered an error when handling a message from subject {Subject}.\n {Error}",
                        topicName, ex);

                    //TODO: push to DLQ
                }
            }

            return(await _messagingTransport.SubscribeAsync(topicName, MsgHandler, options?.Transport, cancellationToken));
        }
        public string GetTopicForName(string topicName, bool includePrefix = true)
        {
            topicName = _innerTopicRegistry.GetTopicForName(topicName, false);

            if (string.IsNullOrEmpty(topicName))
            {
                return(topicName);
            }

            return(includePrefix ? $"{GetTopicPrefix()}{topicName}" : topicName);
        }
예제 #5
0
        public async Task PublishAsync <TMessage>(TMessage message, CancellationToken cancellationToken = default, Action <MessagingEnvelope> envelopeCustomizer = null, string topicName = null)
        {
            var outgoingEnvelope = PrepareMessageEnvelope(message, envelopeCustomizer);
            var key          = (message as IKeyProvider)?.Key;
            var value        = _messageSerDes.SerializeMessageEnvelope(outgoingEnvelope);
            var newTopicName = _topicRegistry.GetTopicForName(topicName) ??
                               _topicRegistry.GetTopicForMessageType(message.GetType());

            await _topicPublisher.PublishAsync(newTopicName, key, value, cancellationToken);

            await Task.Yield();
        }
예제 #6
0
        public async Task PublishAsync <T>(T message, MessagingPublisherOptions publisherOptions = null,
                                           CancellationToken cancellationToken = default)
        {
            var outgoingEnvelope = PrepareMessageEnvelope(message, publisherOptions?.EnvelopeCustomizer);
            var envelopeData     = _messageSerDes.SerializeMessageEnvelope(outgoingEnvelope);

            var newTopicName = _topicRegistry.GetTopicForName(publisherOptions?.TopicName) ??
                               _topicRegistry.GetTopicForMessageType(message.GetType());

            await _messagingTransport.PublishAsync(newTopicName, envelopeData, cancellationToken);

            _logger.LogDebug("Messaging publisher sent a message for subject {Subject}", newTopicName);
            await Task.Yield();
        }
예제 #7
0
        public async Task <HostedSubscription> SubscribeAsync(PipelineDelegate <MessagingContext> pipeline,
                                                              MessagingSubscriberOptions options  = null,
                                                              CancellationToken cancellationToken = default)
        {
            var topicName = _topicRegistry.GetTopicForName(options?.TopicName, false) ??
                            _topicRegistry.GetTopicForMessageType(typeof(TMessage), false);

            Task HandleMsg(MessagingEnvelope <TMessage> msg) => _executionMonitor.Handle(() => Handle(msg, topicName, pipeline, cancellationToken));

            _logger.LogInformation("Messaging subscriber for topic {TopicName} is starting", topicName);

            var subscription = await _messageBus.SubscribeAsync <TMessage>(HandleMsg, options, cancellationToken);

            return(new HostedSubscription(subscription, topicName, _logger));
        }
 public MessagingTopicSubscriberService(
     string topic,
     IMessageSerDes messageSerDes,
     IMessagingTopicSubscriber messagingTopicSubscriber,
     IServiceProvider serviceProvider,
     MessagingContextAccessor messagingContextAccessor,
     ITopicRegistry topicRegistry,
     ILogger <MessagingTopicSubscriberService> logger,
     MessagingSubscriberOptions subscriberOptions = null)
 {
     _messagingTopicSubscriber = messagingTopicSubscriber;
     _serviceProvider          = serviceProvider;
     _messagingContextAccessor = messagingContextAccessor;
     _messageSerDes            = messageSerDes;
     _logger            = logger;
     _subscriberOptions = subscriberOptions;
     _topic             = topicRegistry.GetTopicForName(topic);
 }
예제 #9
0
        public Task SubscribeAsync(Func <MessagingEnvelope <TMessage>, Task> handler, CancellationToken cancellationToken = default, string topicName = null, MessagingSubscriberOptions options = null)
        {
            _handlers.Add(handler);

            if (!_subscribedToTopic)
            {
                lock (lockObj)
                {
                    if (!_subscribedToTopic)
                    {
                        _subscribedToTopic = true;
                        _topicName         = _topicRegistry.GetTopicForName(topicName) ??
                                             _topicRegistry.GetTopicForMessageType(typeof(TMessage));
                        _subscriberOptions = options;
                        _topicSubscriber.SubscribeAsync(_topicName, HandleMessage, cancellationToken, options);
                    }
                }
            }

            return(Task.CompletedTask);
        }