private async Task FuturePublishInternalAsync <T>(TimeSpan messageDelay, T message, string cancellationKey = null) where T : class
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay");
            Preconditions.CheckNull(cancellationKey, "cancellationKey");

            var exchangeName       = conventions.ExchangeNamingConvention(typeof(T));
            var futureExchangeName = exchangeName + "_delayed";
            var queueName          = conventions.QueueNamingConvention(typeof(T), null);
            var futureExchange     = await advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Direct, delayed : true).ConfigureAwait(false);

            var exchange = await advancedBus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, exchange, "#").ConfigureAwait(false);

            var queue = await advancedBus.QueueDeclareAsync(queueName).ConfigureAwait(false);

            await advancedBus.BindAsync(exchange, queue, "#").ConfigureAwait(false);

            var easyNetQMessage = new Message <T>(message)
            {
                Properties =
                {
                    DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T)),
                    Headers      = new Dictionary <string,                                object>{
                        { "x-delay", (int)messageDelay.TotalMilliseconds }
                    }
                }
            };
            await advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage).ConfigureAwait(false);
        }
Exemplo n.º 2
0
        public Task FuturePublishAsync <T>(TimeSpan messageDelay, T message) where T : class
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay");
            var delay              = Round(messageDelay);
            var delayString        = delay.ToString(@"dd\_hh\_mm\_ss");
            var exchangeName       = conventions.ExchangeNamingConvention(typeof(T));
            var futureExchangeName = exchangeName + "_" + delayString;
            var futureQueueName    = conventions.QueueNamingConvention(typeof(T), delayString);

            return(advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Topic)
                   .Then(futureExchange => advancedBus.QueueDeclareAsync(futureQueueName, perQueueTtl: (int)delay.TotalMilliseconds, deadLetterExchange: exchangeName)
                         .Then(futureQueue => advancedBus.BindAsync(futureExchange, futureQueue, "#"))
                         .Then(() =>
            {
                var easyNetQMessage = new Message <T>(message)
                {
                    Properties =
                    {
                        DeliveryMode = (byte)(messageDeliveryModeStrategy.IsPersistent(typeof(T)) ? 2 : 1)
                    }
                };
                return advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage);
            })));
        }
Exemplo n.º 3
0
        public async Task <IDisposable> AddSubscription <TEvent>(string sourceBoundedContextName,
                                                                 string publishedLanguageEntity)
            where TEvent : class
        {
            var queue = await _messageBus.QueueDeclareAsync(NamingConventions.QueueNamingConvention(_boundedContextName,
                                                                                                    sourceBoundedContextName, publishedLanguageEntity, _subscriberId));

            await _messageBus.BindAsync(
                new Exchange(
                    NamingConventions.ExchangeNamingConvention(sourceBoundedContextName, publishedLanguageEntity)),
                queue, "");

            return(_messageBus.Consume(queue, async(bytes, properties, info) =>
            {
                var msg = Encoding.UTF8.GetString(bytes);

                Console.WriteLine(msg);
                var validationResult = await _schemaValidator.IsValid <TEvent>(msg);
                if (validationResult.IsValid)
                {
                    var envelope = System.Text.Json.JsonSerializer.Deserialize <Envelope <TEvent> >(msg);
                    var props = new MessageProperties();
                    properties.CopyTo(props);
                    await _eventDispatcher.HandleEvent(envelope, props);
                }
                else
                {
                    throw new Exception($"Schema is invalid, errors: {string.Join(", ", validationResult.Errors)}");
                }
            }));
        }
Exemplo n.º 4
0
        private async Task FuturePublishInternalAsync <T>(TimeSpan messageDelay, T message, string cancellationKey) where T : class
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay");
            Preconditions.CheckNull(cancellationKey, "cancellationKey");
            var delay              = Round(messageDelay);
            var delayString        = delay.ToString(@"dd\_hh\_mm\_ss");
            var exchangeName       = conventions.ExchangeNamingConvention(typeof(T));
            var futureExchangeName = exchangeName + "_" + delayString;
            var futureQueueName    = conventions.QueueNamingConvention(typeof(T), delayString);
            var futureExchange     = await advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Topic).ConfigureAwait(false);

            var futureQueue = await advancedBus.QueueDeclareAsync(futureQueueName, perQueueMessageTtl : (int)delay.TotalMilliseconds, deadLetterExchange : exchangeName).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, futureQueue, "#").ConfigureAwait(false);

            var easyNetQMessage = new Message <T>(message)
            {
                Properties =
                {
                    DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T))
                }
            };
            await advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage).ConfigureAwait(false);
        }
        /// <inheritdoc />
        public async Task FuturePublishAsync <T>(
            T message,
            TimeSpan delay,
            Action <IFuturePublishConfiguration> configure,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new FuturePublishConfiguration(conventions.TopicNamingConvention(typeof(T)));

            configure(publishConfiguration);

            var topic    = publishConfiguration.Topic;
            var exchange = await exchangeDeclareStrategy.DeclareExchangeAsync(
                conventions.ExchangeNamingConvention(typeof(T)),
                ExchangeType.Topic,
                cts.Token
                ).ConfigureAwait(false);

            var delayString    = delay.ToString(@"dd\_hh\_mm\_ss");
            var futureExchange = await exchangeDeclareStrategy.DeclareExchangeAsync(
                $"{conventions.ExchangeNamingConvention(typeof(T))}_{delayString}",
                ExchangeType.Topic,
                cts.Token
                ).ConfigureAwait(false);

            var futureQueue = await advancedBus.QueueDeclareAsync(
                conventions.QueueNamingConvention(typeof(T), delayString),
                c =>
            {
                c.WithMessageTtl(delay);
                c.WithDeadLetterExchange(exchange);
                if (setDeadLetterRoutingKey)
                {
                    c.WithDeadLetterRoutingKey(topic);
                }
            },
                cts.Token
                ).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, futureQueue, topic, cts.Token).ConfigureAwait(false);

            var properties = new MessageProperties();

            if (publishConfiguration.Priority != null)
            {
                properties.Priority = publishConfiguration.Priority.Value;
            }
            properties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T));

            var advancedMessage = new Message <T>(message, properties);
            await advancedBus.PublishAsync(
                futureExchange, topic, configuration.MandatoryPublish, advancedMessage, cts.Token
                ).ConfigureAwait(false);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Bind an exchange to a queue. Does nothing if the binding already exists.
        /// </summary>
        /// <param name="bus">The bus instance</param>
        /// <param name="exchange">The exchange to bind</param>
        /// <param name="queue">The queue to bind</param>
        /// <param name="routingKey">The routing key</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>A binding</returns>
        public static IBinding Bind(this IAdvancedBus bus, IExchange exchange, IQueue queue, string routingKey, CancellationToken cancellationToken = default)
        {
            Preconditions.CheckNotNull(bus, "bus");

            return(bus.BindAsync(exchange, queue, routingKey, cancellationToken)
                   .GetAwaiter()
                   .GetResult());
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates a queue and its associated exchange on the message broker.  If the associated
        /// exchange is the RabbitMQ default exchange, only the queue is created.  For a non-default
        /// exchange, the queue is bound to the exchange.  If the metadata has route-keys specified,
        /// the queue is bound the to exchange for each specified key.
        /// </summary>
        /// <param name="bus">Reference to the advanced bus.</param>
        /// <param name="meta">The metadata describing the queue.</param>
        /// <returns>Reference to the created queue.</returns>
        public static async Task <IQueue> QueueDeclare(this IAdvancedBus bus, QueueMeta meta)
        {
            if (bus == null)
            {
                throw new ArgumentNullException(nameof(bus));
            }
            if (meta == null)
            {
                throw new ArgumentNullException(nameof(meta));
            }

            IExchange    exchange     = Exchange.GetDefault(); //  Assume default exchange.
            ExchangeMeta exchangeMeta = meta.Exchange;

            if (!meta.Exchange.IsDefaultExchange)
            {
                exchange = await bus.ExchangeDeclareAsync(exchangeMeta.ExchangeName, exchangeMeta.ExchangeType,
                                                          durable : exchangeMeta.IsDurable,
                                                          autoDelete : exchangeMeta.IsAutoDelete,
                                                          passive : exchangeMeta.IsPassive,
                                                          alternateExchange : exchangeMeta.AlternateExchangeName);
            }

            IQueue queue = await bus.QueueDeclareAsync(meta.ScopedQueueName,
                                                       durable : meta.IsDurable,
                                                       autoDelete : meta.IsAutoDelete,
                                                       exclusive : meta.IsExclusive,
                                                       passive : meta.IsPassive,
                                                       maxPriority : meta.MaxPriority,
                                                       deadLetterExchange : meta.DeadLetterExchange,
                                                       deadLetterRoutingKey : meta.DeadLetterRoutingKey,
                                                       perQueueMessageTtl : meta.PerQueueMessageTtl);


            // Queues defined on the default exchange so don't bind.
            if (exchangeMeta.IsDefaultExchange)
            {
                return(queue);
            }

            string[] routeKeys = meta.RouteKeys ?? new string[] { };
            if (routeKeys.Length > 0)
            {
                // If route-keys specified, bind the queue to the exchange
                // for each route-key.
                foreach (string routeKey in meta.RouteKeys ?? new string[] {})
                {
                    bus.Bind(exchange, queue, routeKey);
                }
            }
            else
            {
                await bus.BindAsync(exchange, queue, string.Empty);
            }

            return(queue);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Bind two exchanges. Does nothing if the binding already exists.
        /// </summary>
        /// <param name="bus">The bus instance</param>
        /// <param name="source">The source exchange</param>
        /// <param name="destination">The destination exchange</param>
        /// <param name="routingKey">The routing key</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>A binding</returns>
        public static Task <IBinding> BindAsync(
            this IAdvancedBus bus,
            IExchange source,
            IExchange destination,
            string routingKey,
            CancellationToken cancellationToken
            )
        {
            Preconditions.CheckNotNull(bus, "bus");

            return(bus.BindAsync(source, destination, routingKey, null, cancellationToken));
        }
Exemplo n.º 9
0
        private async Task <EasyNetQ.Topology.IExchange> BindExchangeWithMessageQueueAsync(string exchangename)
        {
            _logger.LogDebug("BindExchangeWithMessageQueueAsync() started.");

            var exchange = await _advancedBus.ExchangeDeclareAsync(exchangename, ExchangeType.Topic);

            var queue = await InitializeGetQueuesAsync();

            var binding = await _advancedBus.BindAsync(exchange, queue, string.Empty);

            _logger.LogDebug("BindExchangeWithMessageQueueAsync() completed.");
            return(exchange);
        }
Exemplo n.º 10
0
        private async Task <string> SubscribeToReplyAsync(CancellationToken cancellationToken)
        {
            if (_replyQueue != null)
            {
                return(_replyQueue);
            }

            using (await _replyQueueLock.AcquireAsync(cancellationToken))
            {
                if (_replyQueue != null)
                {
                    return(_replyQueue);
                }

                var replyQueue = $"toxon.micro.rpc.reply.{Guid.NewGuid()}";

                var exchange = await _bus.ExchangeDeclareAsync(ReplyExchangeName, ExchangeType.Direct);

                var queue = await _bus.QueueDeclareAsync(replyQueue);

                await _bus.BindAsync(exchange, queue, replyQueue);

                _bus.Consume(queue, (body, props, info) =>
                {
                    var correlationIdString = props.CorrelationId;

                    if (Guid.TryParse(correlationIdString, out var correlationId) && _responseHandlers.TryRemove(correlationId, out var tcs))
                    {
                        tcs.SetResult(MessageHelpers.FromArgs(body, props));
                    }
                });

                _replyQueue = replyQueue;
                return(_replyQueue);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Bind two exchanges. Does nothing if the binding already exists.
        /// </summary>
        /// <param name="bus">The bus instance</param>
        /// <param name="source">The source exchange</param>
        /// <param name="destination">The destination exchange</param>
        /// <param name="routingKey">The routing key</param>
        /// <param name="headers">The headers</param>
        /// <param name="cancellationToken">The cancellation token</param>
        /// <returns>A binding</returns>
        public static IBinding Bind(
            this IAdvancedBus bus,
            IExchange source,
            IExchange destination,
            string routingKey,
            IDictionary <string, object> headers,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(bus, "bus");

            return(bus.BindAsync(source, destination, routingKey, headers, cancellationToken)
                   .GetAwaiter()
                   .GetResult());
        }
 private Task<IExchange> DeclareVersionedExchanges(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType)
 {
     var destinationExchangeTask = TaskHelpers.FromResult<IExchange>(null);
     while (! messageVersions.IsEmpty())
     {
         var messageType = messageVersions.Pop();
         var exchangeName = conventions.ExchangeNamingConvention(messageType);
         destinationExchangeTask = destinationExchangeTask.Then(destinationExchange => DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).Then(sourceExchange =>
             {
                 if (destinationExchange != null)
                     return advancedBus.BindAsync(sourceExchange, destinationExchange, "#").Then(() => sourceExchange);
                 return TaskHelpers.FromResult(sourceExchange);
             }));
     }
     return destinationExchangeTask;
 }
Exemplo n.º 13
0
        /// <inheritdoc />
        public async Task FuturePublishAsync <T>(
            T message,
            TimeSpan delay,
            Action <IFuturePublishConfiguration> configure,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new FuturePublishConfiguration(conventions.TopicNamingConvention(typeof(T)));

            configure(publishConfiguration);

            var topic              = publishConfiguration.Topic;
            var exchangeName       = conventions.ExchangeNamingConvention(typeof(T));
            var futureExchangeName = exchangeName + "_delayed";
            var futureExchange     = await advancedBus.ExchangeDeclareAsync(
                futureExchangeName,
                c => c.AsDelayedExchange(ExchangeType.Topic),
                cts.Token
                ).ConfigureAwait(false);

            var exchange = await advancedBus.ExchangeDeclareAsync(
                exchangeName,
                c => c.WithType(ExchangeType.Topic),
                cts.Token
                ).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, exchange, topic, cts.Token).ConfigureAwait(false);

            var properties = new MessageProperties();

            if (publishConfiguration.Priority != null)
            {
                properties.Priority = publishConfiguration.Priority.Value;
            }
            properties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T));

            await advancedBus.PublishAsync(
                futureExchange, topic, false, new Message <T>(message, properties).WithDelay(delay), cts.Token
                ).ConfigureAwait(false);
        }
Exemplo n.º 14
0
        private async Task <IExchange> DeclareVersionedExchangesAsync(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType)
        {
            IExchange destinationExchange = null;

            while (!messageVersions.IsEmpty())
            {
                var messageType    = messageVersions.Pop();
                var exchangeName   = conventions.ExchangeNamingConvention(messageType);
                var sourceExchange = await DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).ConfigureAwait(false);

                if (destinationExchange != null)
                {
                    await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false);
                }
                destinationExchange = sourceExchange;
            }
            return(destinationExchange);
        }
Exemplo n.º 15
0
        private Task <IExchange> DeclareVersionedExchanges(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType)
        {
            var destinationExchangeTask = TaskHelpers.FromResult <IExchange>(null);

            while (!messageVersions.IsEmpty())
            {
                var messageType  = messageVersions.Pop();
                var exchangeName = conventions.ExchangeNamingConvention(messageType);
                destinationExchangeTask = destinationExchangeTask.Then(destinationExchange => DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).Then(sourceExchange =>
                {
                    if (destinationExchange != null)
                    {
                        return(advancedBus.BindAsync(sourceExchange, destinationExchange, "#").Then(() => sourceExchange));
                    }
                    return(TaskHelpers.FromResult(sourceExchange));
                }));
            }
            return(destinationExchangeTask);
        }
Exemplo n.º 16
0
        public async Task DeclareAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Entering {nameof(DeclareAsync)}");

            try
            {
                var exchange = await _advancedBus.ExchangeDeclareAsync(name : _exchanges.ExchangeKey, type : ExchangeType.Direct, cancellationToken : cancellationToken).ConfigureAwait(false);

                var queue = await _advancedBus.QueueDeclareAsync(name : _queues.QueueKey, durable : true, exclusive : false, autoDelete : false, cancellationToken : cancellationToken).ConfigureAwait(false);

                await _advancedBus.BindAsync(exchange : exchange, queue : queue, routingKey : _routings.RoutingKey, headers : null, cancellationToken : cancellationToken).ConfigureAwait(false);

                _logger.LogInformation($"Bind - Exchange: {_exchanges.ExchangeKey}, Queue: {_queues.QueueKey}, RoutingKey: {_routings.RoutingKey}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw;
            }
        }
Exemplo n.º 17
0
        public async Task <IExchange> DeclareExchangeAsync(IAdvancedBus advancedBus, Type messageType, string exchangeType)
        {
            var conventions        = advancedBus.Container.Resolve <IConventions>();
            var sourceExchangeName = conventions.ExchangeNamingConvention(messageType);
            var sourceExchange     = await DeclareExchangeAsync(advancedBus, sourceExchangeName, exchangeType).ConfigureAwait(false);

            var interfaces = messageType.GetInterfaces();

            foreach (var @interface in interfaces)
            {
                var destinationExchangeName = conventions.ExchangeNamingConvention(@interface);
                var destinationExchange     = await DeclareExchangeAsync(advancedBus, destinationExchangeName, exchangeType);

                if (destinationExchange != null)
                {
                    await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false);
                }
            }

            return(sourceExchange);
        }
Exemplo n.º 18
0
        public async Task SubscribeAsync(Func <string, CancellationToken, Task> processMessageAsync, CancellationToken cancellationToken)
        {
            _logger.LogInformation($"Entering {nameof(SubscribeAsync)}");

            try
            {
                var exchange = await _advancedBus.ExchangeDeclareAsync(name : _exchanges.ExchangeKey, type : ExchangeType.Direct, cancellationToken : cancellationToken).ConfigureAwait(false);

                var queue = await _advancedBus.QueueDeclareAsync(name : _queues.QueueKey, durable : true, exclusive : false, autoDelete : false, cancellationToken : cancellationToken).ConfigureAwait(false);

                await _advancedBus.BindAsync(exchange : exchange, queue : queue, routingKey : _routings.RoutingKey, headers : null, cancellationToken : cancellationToken).ConfigureAwait(false);

                _advancedBus.Consume(queue, (body, _, _) => Task.Factory.StartNew(async() =>
                {
                    var message = Encoding.UTF8.GetString(body);
                    await processMessageAsync(message, cancellationToken).ConfigureAwait(false);
                }, cancellationToken));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw;
            }
        }
 private async Task<IExchange> DeclareVersionedExchangesAsync(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType)
 {
     IExchange destinationExchange = null;
     while (! messageVersions.IsEmpty())
     {
         var messageType = messageVersions.Pop();
         var exchangeName = conventions.ExchangeNamingConvention(messageType);
         var sourceExchange = await DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).ConfigureAwait(false);
         if (destinationExchange != null)
         {
             await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false);
         }
         destinationExchange = sourceExchange;
     }
     return destinationExchange;
 }
Exemplo n.º 20
0
        private async Task <ISubscriber> CreateSubscriberAsync(string name, bool temporary, Action temporaryQueueDisconnected,
                                                               IEnumerable <string> routings, int retrycount, int prefetchcount, bool explicitAcknowledgments, ISubscriptionSelector subscriptionSelector, bool storedeadletter)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("name argument can not be null or empty");
            }

            if ((routings != null) && (routings.Any(routing => string.IsNullOrEmpty(routing)) || !routings.Any()))
            {
                throw new ArgumentException("routings argument can not be empty or contain empty strings");
            }

            if (retrycount < 0)
            {
                throw new ArgumentException("retrycount argument can not be less than zero");
            }

            if (temporaryQueueDisconnected != null)
            {
                _broker.RegisterDisconnectedAction(temporaryQueueDisconnected);
            }

            //Main subscriber queue and bindings
            var queue = await _bus.QueueDeclareAsync(
                _environmentNamingConventionController.GetQueueName(name), false, true, temporary);

            if (routings != null)
            {
                foreach (var routing in routings)
                {
                    await _bus.BindAsync(await _exchange, queue, routing);
                }
            }

            //Retry subscriber queue and bindings
            for (int i = 1; i <= retrycount; i++)
            {
                var retryqueueroutingkey = _environmentNamingConventionController.GetRetryRoutingKey(name, i);
                var retryqueuequeuename  = _environmentNamingConventionController.GetRetryQueueName(name, i);
                var queueretrybinding    = await _bus.BindAsync(await _exchange, queue,
                                                                retryqueueroutingkey);

                var retryqueue = await _bus.QueueDeclareAsync(retryqueuequeuename,
                                                              false, true, temporary, false, _retryfactor *i, null, null, (await _exchange).Name);

                var retryqueuebinding =
                    await _bus.BindAsync(_easyNetQPublisherToWaitExchange.Exchange,
                                         retryqueue, retryqueueroutingkey);
            }



            //Dead letter subscriber queue and bindings
            if (storedeadletter)
            {
                var deadletterqueueroutingkey = _environmentNamingConventionController
                                                .GetDeadLetterQueueRoutingKey(name);
                var deadletterqueuequeuename = _environmentNamingConventionController.
                                               GetDeadLetterQueueName(name);
                var deadletterqueue = await _bus.QueueDeclareAsync(deadletterqueuequeuename, false, true, temporary);

                var deadletterqueuebinding = await
                                             _bus.BindAsync(_easyNetQPublisherToWaitExchange.Exchange, deadletterqueue,
                                                            deadletterqueueroutingkey);
            }

            //Direct Routing Key binding
            var directroutingkey             = _environmentNamingConventionController.GetDirectRoutingKey(name);
            var queuedirectroutingkeybinding = await _bus.BindAsync(await _exchange, queue,
                                                                    directroutingkey);


            if (_subscriberController.RegisterSubscriberName(name, out IDisposable nameHandle))
            {
                var executionHandler = new ExecutionHandlingStrategy(name, _easyNetQPublisherToWaitExchange,
                                                                     retrycount, _environmentNamingConventionController, explicitAcknowledgments, _publisher, storedeadletter);
                return(new EasyNetQSubscriber(executionHandler, _bus, queue, (ushort)prefetchcount,
                                              subscriptionSelector, executionHandler, nameHandle));
            }
            else
            {
                throw new SubscriberAlreadyExistsException($"The subscriber " +
                                                           $"with name {name}" +
                                                           $" already exists");
            }
        }
Exemplo n.º 21
0
        private async Task <ISubscriptionResult> SubscribeAsyncInternal <T>(
            string subscriptionId,
            Func <T, CancellationToken, Task> onMessage,
            Action <ISubscriptionConfiguration> configure,
            CancellationToken cancellationToken
            )
        {
            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var subscriptionConfiguration = new SubscriptionConfiguration(configuration.PrefetchCount);

            configure(subscriptionConfiguration);

            var queueName    = subscriptionConfiguration.QueueName ?? conventions.QueueNamingConvention(typeof(T), subscriptionId);
            var exchangeName = conventions.ExchangeNamingConvention(typeof(T));

            var queue = await advancedBus.QueueDeclareAsync(
                queueName,
                c =>
            {
                c.AsDurable(subscriptionConfiguration.Durable);
                c.AsAutoDelete(subscriptionConfiguration.AutoDelete);
                if (subscriptionConfiguration.Expires.HasValue)
                {
                    c.WithExpires(TimeSpan.FromMilliseconds(subscriptionConfiguration.Expires.Value));
                }
                if (subscriptionConfiguration.MaxPriority.HasValue)
                {
                    c.WithMaxPriority(subscriptionConfiguration.MaxPriority.Value);
                }
                if (subscriptionConfiguration.MaxLength.HasValue)
                {
                    c.WithMaxLength(subscriptionConfiguration.MaxLength.Value);
                }
                if (subscriptionConfiguration.MaxLengthBytes.HasValue)
                {
                    c.WithMaxLengthBytes(subscriptionConfiguration.MaxLengthBytes.Value);
                }
                if (!string.IsNullOrEmpty(subscriptionConfiguration.QueueMode))
                {
                    c.WithQueueMode(subscriptionConfiguration.QueueMode);
                }
            },
                cts.Token
                ).ConfigureAwait(false);

            var exchange = await advancedBus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic, cancellationToken : cts.Token).ConfigureAwait(false);

            foreach (var topic in subscriptionConfiguration.Topics.DefaultIfEmpty("#"))
            {
                await advancedBus.BindAsync(exchange, queue, topic, cts.Token).ConfigureAwait(false);
            }

            var consumerCancellation = advancedBus.Consume <T>(
                queue,
                (message, messageReceivedInfo) => onMessage(message.Body, default),
                x => x.WithPriority(subscriptionConfiguration.Priority)
                .WithPrefetchCount(subscriptionConfiguration.PrefetchCount)
                .WithExclusive(subscriptionConfiguration.IsExclusive)
                );

            return(new SubscriptionResult(exchange, queue, consumerCancellation));
        }