private bool TryGetPayloadAndHeaders(
            IMessageSubscription subscription,
            out object payload,
            out MessageHeaders headers)
        {
            payload = null;
            headers = null;

            try
            {
                var payloadType  = subscription.MessageType;
                var payloadBytes = CurrentMessage.Body.ToArray();

                payload = MessagePackSerializer.NonGeneric.Deserialize(payloadType, payloadBytes, _formatterResolver);
                headers = new MessageHeaders(CurrentMessage.CorrelationId);

                return(true);
            }
            catch (Exception e)
            {
                CurrentLog.Warning(CurrentMessage, $"Failed to deserialize the message. Processor #{_id}.", e);

                _rejectManager.ScheduleReject(CurrentMessage, rejectAfter: TimeSpan.FromMinutes(10));

                return(false);
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Adds <paramref name="messageSubscription" /> to the bus.
        /// </summary>
        /// <param name="messageSubscription">Message subscriptions</param>
        public void Subscribe(IMessageSubscription messageSubscription)
        {
            lock (this.subscriptions)
                this.subscriptions.Add(messageSubscription);

            this.trace.TraceEvent(TraceEventType.Verbose, 0, "Subscription added: '{0}'", messageSubscription.Id);
        }
        public void SetupBeforeEachTest()
        {
            this.messageSubscription = A.Fake<IMessageSubscription>();

             A.CallTo(() => this.MessageSubscriptionFactory.Create(A<Type>._)).Returns(this.messageSubscription);

             this.componentUnderTest = this.CreateInMemoryServiceBus();
        }
Beispiel #4
0
        public ISubscription Subscribe(string subject, string queueGroup, IMessageSubscription handler)
        {
            var sid = GetNextSid();

            subscriptions.Sub(subject, sid, handler);
            nats.Send(NatsOperationId.SUB, new SubOperation(subject, queueGroup, sid));
            return(new Subscription(this, subject, queueGroup, sid));
        }
        public void SetupBeforeEachTest()
        {
            this.messageSubscription = A.Fake<IMessageSubscription>();

             A.CallTo(() => this.MessageSubscriptionFactory.Create(A<IChannelManagerFactory>._, A<Type[]>._)).Returns(this.messageSubscription);

             this.componentUnderTest = this.CreateRabbitMQServiceBus();
        }
        protected virtual bool TryResolveSubscription <TMessage>([NotNullWhen(true)] out IMessageSubscription <TClientService, TMessage>?subscription) where TMessage : IMessage
#endif
        {
#if NETCOREAPP3_0 || NETCOREAPP3_1
            subscription = null;
#else
            Unsafe.SkipInit(out subscription);
#endif
            ref IMessageSubscription?s = ref Unsafe.As <IMessageSubscription <TClientService, TMessage>?, IMessageSubscription?>(ref subscription);
Beispiel #7
0
        /// <summary>
        /// Sends a message that will be received by any subscriptions that can handle the parameters in the order sent in
        /// </summary>
        /// <param name="objects">The parameters to send to the subscriptions</param>
        public void Send(params object[] objects)
        {
            if (objects is null)
            {
                throw new ArgumentNullException(nameof(objects));
            }

            for (int i = 0; i < Subscriptions.Count; i++)
            {
                IMessageSubscription subscription = Subscriptions[i];
                if (MessageMatch(subscription, objects))
                {
                    subscription.Invoke(objects, this.ServiceProvider);
                }
            }
        }
        private bool TryGetSubscription(
            out IMessageSubscription subscription)
        {
            subscription = _subscriptionsRegistry.GetSubscriptionOrDefault(CurrentMessage.RoutingKey);

            if (subscription != null)
            {
                return(true);
            }
            else
            {
                CurrentLog.Warning(CurrentMessage, $"Subscription for the message has not been found. Processor #{_id}.");

                _rejectManager.ScheduleReject(CurrentMessage, rejectAfter: TimeSpan.FromMinutes(10));

                return(false);
            }
        }
Beispiel #9
0
        private static bool MessageMatch(IMessageSubscription subscription, params object[] messageArgs)
        {
            if (subscription.Parameters.Count() != messageArgs.Length)
            {
                return(false);
            }

            for (int i = 0; i < subscription.Parameters.Count(); i++)
            {
                Type argsType = messageArgs[i].GetType();

                if (!subscription.Parameters.ElementAt(i).IsAssignableFrom(argsType))
                {
                    return(false);
                }
            }

            return(true);
        }
        private async Task ProcessMessageAsync(
            IMessageSubscription subscription,
            EnvelopedMessage envelopedMessage,
            object payload,
            MessageHeaders headers)
        {
            var publisher = _repliesPublisher?.Invoke(headers.CorrelationId)
                            ?? ProhibitedRepliesMessagePublisher.Instance;

            var handlingContext = new MessageHandlingContext
                                  (
                envelopedMessage.Exchange,
                envelopedMessage.RetryCount,
                envelopedMessage.RoutingKey
                                  );
            var result = await subscription.InvokeHandlerAsync(_serviceProvider, payload, headers, handlingContext, publisher);

            if (result == null)
            {
                throw new InvalidOperationException("Result should be not null");
            }

            switch (result)
            {
            case MessageHandlingResult.SuccessResult _:
            case MessageHandlingResult.NonTransientFailureResult _:
                CurrentMessage.Ack();
                break;

            case MessageHandlingResult.TransientFailureResult tfr:
                _retryManager.ScheduleRetry(CurrentMessage, tfr.RetryAfter ?? _defaultRetryTimeout);
                break;

            default:
                throw new NotSupportedException($"Unexpected message handling result [{result.GetType().Name}].");
            }
        }
Beispiel #11
0
        /// <summary>
        ///     Removes the <paramref name="messageSubscription" /> from the bus.
        /// </summary>
        /// <param name="messageSubscription">Message subscription</param>
        public void Unsubscribe(IMessageSubscription messageSubscription)
        {
            lock (this.subscriptions)
                this.subscriptions.Remove(messageSubscription);

            this.trace.TraceEvent(TraceEventType.Verbose, 0, "Subscription removed: '{0}'", messageSubscription.Id);
        }
Beispiel #12
0
 public static ValueTask SubscribeWithLog(this IMessageSubscription subscription, ILogger log)
 => subscription.Subscribe(
     id => log.LogInformation("{Subscription} subscribed", id),
     (id, reason, ex) => log.LogWarning(ex, "{Subscription} dropped {Reason}", id, reason),
     CancellationToken.None
     );
Beispiel #13
0
 public void Sub(string subject, string sid, IMessageSubscription handler)
 {
     subscriptions.Sub(subject, sid, handler);
     nats.Send(NatsOperationId.SUB, new SubOperation(subject, sid));
 }
 protected virtual bool TryResolveSubscription <TMessage>(out IMessageSubscription <TClientService, TMessage>?subscription) where TMessage : IMessage
 public static ISubscription Subscribe(this NatsClient nats, string subject, IMessageSubscription handler)
 => nats.Subscribe(subject, default, handler);
Beispiel #16
0
 /// <summary>
 /// Adds a new message subscription to the state
 /// </summary>
 /// <param name="subscription">the message subscription to add to the state</param>
 public void Subscribe(IMessageSubscription subscription)
 {
     _subscriptions.Add(subscription);
 }
Beispiel #17
0
 public static ValueTask UnsubscribeWithLog(this IMessageSubscription subscription, ILogger log)
 => subscription.Unsubscribe(
     id => log.LogInformation("{Subscription} unsubscribed", id),
     CancellationToken.None
     );