Beispiel #1
0
        public Task PublishAsync(string topicName, byte[] message, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(topicName))
            {
                throw new ArgumentException("TopicName is null or empty", nameof(topicName));
            }

            var tcs = new TaskCompletionSource <bool>();

            lock (_publisherAsyncLock)
            {
                if (_publisherChannel == null)
                {
                    var connection = _connection.GetConnection();
                    _publisherChannel = connection.CreateModel();
                    _publisherChannel.ConfirmSelect();
                    _publisherChannel.BasicAcks  += (sender, ea) => ExecuteUnconfirmedActions(_publisherUnconfirmedActions, ea.DeliveryTag, ea.Multiple, true);
                    _publisherChannel.BasicNacks += (sender, ea) => ExecuteUnconfirmedActions(_publisherUnconfirmedActions, ea.DeliveryTag, ea.Multiple, false);
                }

                var props = _publisherChannel.CreateBasicProperties();
                props.DeliveryMode = 2; // persistent delivery mode
                var nextPublishSeqNo = _publisherChannel.NextPublishSeqNo;

                RegisterUnconfirmedAction(_publisherUnconfirmedActions, tcs, nextPublishSeqNo, cancellationToken);

                var routingKey = RabbitMapper.GetRoutingKey(topicName);
                _publisherChannel.BasicPublish(_rabbitOptions.Exchange, routingKey, props, message);
                _logger.LogDebug("Published message with topic [{}]", topicName);
            }

            return(tcs.Task);
        }
Beispiel #2
0
        public async Task StartConsumeAsync_Test(bool autoDelete)
        {
            int maxConcurrentMessages = 100;
            var queueName             = RabbitMapper.GetQueueName(_serviceName, _topicName);

            var consumer = new RabbitConsumer(_connection, _serviceName, _topicName, MessageHandler,
                                              () => { }, false, maxConcurrentMessages, _options, _logger);

            // first start
            await consumer.StartConsumeAsync(_cancellationTokenSource.Token);

            A.CallTo(() => _rabbitChannel.BasicQos(0, (ushort)maxConcurrentMessages, false))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() => _rabbitChannel.QueueDeclare(queueName, true, false, false, null))
            .MustHaveHappenedOnceExactly();

            A.CallTo(() => _rabbitChannel.ExchangeDeclare(_options.Exchange, ExchangeType.Direct, true, false, null))
            .MustHaveHappenedOnceExactly();

            A.CallTo(() => _rabbitChannel.QueueBind(queueName, _options.Exchange, _topicName, null))
            .MustHaveHappenedOnceExactly();
            A.CallTo(() =>
                     _rabbitChannel.BasicConsume(queueName, false, "", false, false, null,
                                                 A <AsyncEventingBasicConsumer> .Ignored))
            .MustHaveHappenedOnceExactly();
            Assert.IsTrue(consumer.IsStarted);

            // does not repeat execution if started multiple times
            await consumer.StartConsumeAsync(_cancellationTokenSource.Token);

            A.CallTo(() => _rabbitChannel.QueueDeclare(queueName, true, false, false, null))
            .MustHaveHappenedOnceExactly();
            Assert.IsTrue(consumer.IsStarted);
        }
Beispiel #3
0
        public ResponseModel GetById(int id)
        {
            var rabbit    = _rabbitRepo.GetById(id);
            var rabbitRes = RabbitMapper.ToRabbitResponse(rabbit);

            return(rabbitRes);
        }
Beispiel #4
0
        public List <ResponseModel> GetAll()
        {
            var rabbits         = _rabbitRepo.GetAll().ToList();
            var rabbitResponses = RabbitMapper.ToRabbitResponse(rabbits);

            return(rabbitResponses);
        }
Beispiel #5
0
        public RabbitConsumer(IRabbitFactoryConnection connection,
                              string serviceName, string topicName,
                              Func <GateContext, CancellationToken, Task> messageHandler,
                              Action abortedHandler,
                              bool autoDelete,
                              int maxConcurrentMessages,
                              RabbitOptions options, ILogger logger)
        {
            ServiceName = string.IsNullOrEmpty(serviceName) ?
                          throw new ArgumentException("ServiceName null or empty", nameof(serviceName)) : serviceName;
            TopicName = string.IsNullOrEmpty(topicName) ?
                        throw new ArgumentException("TopicName null or empty", nameof(topicName)) : topicName;
            AutoDelete            = autoDelete;
            MaxConcurrentMessages = maxConcurrentMessages;
            _messageHandler       = messageHandler ?? throw new ArgumentNullException(nameof(messageHandler));

            if (abortedHandler == null)
            {
                throw new ArgumentNullException(nameof(abortedHandler));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            var queueName  = RabbitMapper.GetQueueName(ServiceName, TopicName);
            var routingKey = RabbitMapper.GetRoutingKey(TopicName);

            _consumer = new RabbitInternalConsumer(connection, options.Exchange, queueName, routingKey, AutoDelete, (ushort)MaxConcurrentMessages, HandleMessage,
                                                   abortedHandler);
        }
Beispiel #6
0
        public void UpdateRabbit(RequestModel rabbitReq, int id)
        {
            var rabbit = RabbitMapper.ToRabbit(rabbitReq);

            rabbit.Id = id;

            _rabbitRepo.Update(rabbit);
            _rabbitRepo.SaveChanges();
        }
Beispiel #7
0
        public void AddRabbit(RequestModel rabbitReq)
        {
            var rabbit = RabbitMapper.ToRabbit(rabbitReq);

            rabbit.AddedOn = DateTime.Now;

            _rabbitRepo.Insert(rabbit);
            _rabbitRepo.SaveChanges();
        }
Beispiel #8
0
        public Task <byte[]> RequestAsync(string serviceName, string topicName, byte[] message,
                                          int requestTimeoutInSeconds,
                                          CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(serviceName))
            {
                throw new ArgumentException("ServiceName is null or empty", nameof(serviceName));
            }

            if (string.IsNullOrEmpty(topicName))
            {
                throw new ArgumentException("TopicName is null or empty", nameof(topicName));
            }

            var correlationId = Guid.NewGuid().ToString();
            var tcs           = new TaskCompletionSource <byte[]>();


            lock (_rpcAsyncLock)
            {
                if (_rpcChannel == null)
                {
                    var connection = _connection.GetConnection();
                    _rpcChannel = connection.CreateModel();
                    var consumer = new EventingBasicConsumer(_rpcChannel);
                    _rpcChannel.BasicConsume(consumer, ReplyToQueueName, true);
                    consumer.Received += (sender, ea) => HandleResponse(ea.BasicProperties.CorrelationId, ea.Body.ToArray());
                }

                var props = _rpcChannel.CreateBasicProperties();
                props.ReplyTo       = ReplyToQueueName;
                props.DeliveryMode  = 1;                                           // non persistent delivery mode
                props.Expiration    = (requestTimeoutInSeconds * 1000).ToString(); // timeout in milliseconds as string
                props.CorrelationId = correlationId;

                Timer timeoutTimer = null;
                timeoutTimer = new Timer(state =>
                {
                    _waitingResponses.TryRemove(correlationId, out _);
                    tcs.TrySetException(new TimeoutException($"Timeout waiting response for CorrelationId [{correlationId}]"));
                    timeoutTimer?.Dispose();
                }, null, TimeSpan.FromSeconds(requestTimeoutInSeconds), TimeSpan.FromMilliseconds(-1));

                cancellationToken.Register(() => {
                    _waitingResponses.TryRemove(correlationId, out _);
                    tcs.TrySetException(new OperationCanceledException($"Waiting response canceled for CorrelationId [{correlationId}]"));
                    timeoutTimer?.Dispose();
                });

                _waitingResponses.TryAdd(correlationId, msg => {
                    if (_waitingResponses.TryRemove(correlationId, out _))
                    {
                        tcs.TrySetResult(msg);
                    }
                    timeoutTimer?.Dispose();
                });

                _logger.LogDebug("Publishing request for service [{}] with correlationId [{}]", serviceName, correlationId);
                var queueName = RabbitMapper.GetQueueName(serviceName, topicName);
                _rpcChannel.BasicPublish("", queueName, props, message);
            }

            return(tcs.Task);
        }