public NaosMessagingEchoController(
            ILogger <NaosMessagingEchoController> logger,
            IMessageBroker messageBroker,
            ISubscriptionMap subscriptionMap)
        {
            EnsureArg.IsNotNull(logger, nameof(logger));

            this.logger          = logger;
            this.messageBroker   = messageBroker;
            this.subscriptionMap = subscriptionMap;
        }
Пример #2
0
        public StorageQueueMessageBroker(
            ILogger <StorageQueueMessageBroker> logger,
            string storageConnectionString,
            IMessageHandlerFactory handlerFactory,
            ISubscriptionMap map = null)
        {
            EnsureArg.IsNotNull(logger, nameof(logger));
            EnsureArg.IsNotNullOrEmpty(storageConnectionString, nameof(storageConnectionString));
            EnsureArg.IsNotNull(handlerFactory, nameof(handlerFactory));

            this.logger = logger;
            this.storageConnectionString = storageConnectionString;
            this.map            = map ?? new SubscriptionMap();
            this.handlerFactory = handlerFactory;

            // maybe not a good fit for a message broker
            // https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-azure-and-service-bus-queues-compared-contrasted
            // - no push style api (no onmessage())
            // - single subscriber only (due to message.dequeue), has peek however
        }
Пример #3
0
#pragma warning disable SA1204 // Static elements should appear before instance elements
#pragma warning disable SA1202 // Elements should be ordered by access
        /// <summary>
        /// Processes the message by invoking the message handler.
        /// </summary>
        public static async Task <bool> ProcessMessage(
            ILogger <ServiceBusMessageBroker> logger,
            ITracer tracer,
            ISubscriptionMap subscriptions,
            IMessageHandlerFactory handlerFactory,
            ISerializer serializer,
            string messageScope,
            IMediator mediator,
            Microsoft.Azure.ServiceBus.Message serviceBusMessage)
#pragma warning restore SA1204 // Static elements should appear before instance elements
#pragma warning restore SA1202 // Elements should be ordered by access
        {
            var processed   = false;
            var messageName = serviceBusMessage.Label;

            if (subscriptions.Exists(messageName))
            {
                foreach (var subscription in subscriptions.GetAll(messageName))
                {
                    var messageType = subscriptions.GetByName(messageName);
                    if (messageType == null)
                    {
                        continue;
                    }

                    // get parent span infos from message
                    ISpan parentSpan = null;
                    if (serviceBusMessage.UserProperties.ContainsKey("TraceId") && serviceBusMessage.UserProperties.ContainsKey("SpanId"))
                    {
                        // dehydrate parent span
                        parentSpan = new Span(serviceBusMessage.UserProperties["TraceId"] as string, serviceBusMessage.UserProperties["SpanId"] as string);
                    }

                    using (logger.BeginScope(new Dictionary <string, object>
                    {
                        [LogPropertyKeys.CorrelationId] = serviceBusMessage.CorrelationId,
                        //[LogPropertyKeys.TrackId] = scope.Span.SpanId = allready done in Span ScopeManager (activate)
                    }))
                        using (var scope = tracer?.BuildSpan(messageName, LogKeys.AppMessaging, SpanKind.Consumer, parentSpan).Activate(logger))
                        {
                            // map some message properties to the typed message
                            //var jsonMessage = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(serviceBusMessage.Body), messageType); // TODO: use ISerializer here, compacter messages
                            //var message = jsonMessage as Domain.Message;
                            if (!(serializer.Deserialize(serviceBusMessage.Body, messageType) is Domain.Message message))
                            {
                                return(false);
                            }

                            // TODO: message can be null, skip
                            if (message.Origin.IsNullOrEmpty())
                            {
                                //message.CorrelationId = jsonMessage.AsJToken().GetStringPropertyByToken("CorrelationId");
                                message.Origin = serviceBusMessage.UserProperties.ContainsKey("Origin") ? serviceBusMessage.UserProperties["Origin"] as string : string.Empty;
                            }

                            logger.LogJournal(LogKeys.AppMessaging, $"message processed: {serviceBusMessage.Label} (id={{MessageId}}, service={{Service}}, origin={{MessageOrigin}}, size={serviceBusMessage.Body.Length.Bytes().ToString("#.##")})",
                                              LogPropertyKeys.TrackReceiveMessage, args: new[] { message?.Id, messageScope, message.Origin });
                            logger.LogTrace(LogKeys.AppMessaging, message.Id, serviceBusMessage.Label, LogTraceNames.Message);

                            // construct the handler by using the DI container
                            var handler      = handlerFactory.Create(subscription.HandlerType); // should not be null, did you forget to register your generic handler (EntityMessageHandler<T>)
                            var concreteType = typeof(IMessageHandler <>).MakeGenericType(messageType);

                            var method = concreteType.GetMethod("Handle");
                            if (handler != null && method != null)
                            {
                                if (mediator != null)
                                {
                                    await mediator.Publish(new MessageHandledDomainEvent(message, messageScope)).AnyContext();
                                }

                                await((Task)method.Invoke(handler, new object[] { message as object })).AnyContext();
                            }
                            else
                            {
                                logger.LogWarning("{LogKey:l} process failed, message handler could not be created. is the handler registered in the service provider? (name={MessageName}, service={Service}, id={MessageId}, origin={MessageOrigin})",
                                                  LogKeys.AppMessaging, serviceBusMessage.Label, messageScope, message.Id, message.Origin);
                            }
                        }
                }

                processed = true;
            }
            else
            {
                logger.LogDebug($"{{LogKey:l}} unprocessed: {messageName}", LogKeys.AppMessaging);
            }

            return(processed);
        }
 public ServiceBusMessageBrokerOptionsBuilder Map(ISubscriptionMap map)
 {
     this.Target.Map = map;
     return(this);
 }
 public SignalRServerlessMessageBrokerOptionsBuilder Map(ISubscriptionMap map)
 {
     this.Target.Map = map;
     return(this);
 }
Пример #6
0
 public RabbitMQMessageBrokerOptionsBuilder Subscriptions(ISubscriptionMap subscriptions)
 {
     this.Target.Subscriptions = subscriptions;
     return(this);
 }
Пример #7
0
 public ServiceBusMessageBrokerOptionsBuilder Subscriptions(ISubscriptionMap subscriptions)
 {
     this.Target.Subscriptions = subscriptions;
     return(this);
 }
 public SignalRServerlessMessageBrokerOptionsBuilder Subscriptions(ISubscriptionMap subscriptions)
 {
     this.Target.Subscriptions = subscriptions;
     return(this);
 }
 public FileStorageMessageBrokerOptionsBuilder Subscriptions(ISubscriptionMap subscriptions)
 {
     this.Target.Subscriptions = subscriptions;
     return(this);
 }
 public FileStorageMessageBrokerOptionsBuilder Map(ISubscriptionMap map)
 {
     this.Target.Map = map;
     return(this);
 }