예제 #1
0
        /// <summary>
        /// Sets the messenger up for either sending or receiving a specific message of type <typeparamref name="T"/>.
        /// This will create the <see cref="ServiceBusAdapter"/> but will not set it up for reading the queue.
        /// </summary>
        /// <typeparam name="T">The type of the message we are setting up.</typeparam>
        /// <param name="batchSize">The size of the batch when reading for a queue - used as the pre-fetch parameter of the <see cref="Microsoft.Azure.ServiceBus.Core.MessageReceiver"/>.</param>
        /// <param name="transport">The type of the transport to setup</param>
        /// <param name="topicName">Topic name to be used to create the topic. If not provided the type <typeparam name="T"/> will be used</param>
        /// <returns>The message queue adapter.</returns>
        internal ServiceBusAdapter <T> SetupMessageType <T>(int batchSize, MessagingTransport transport, string topicName)
            where T : class
        {
            ServiceBusAdapter adapter = null;

            if (!ServiceBusAdapters.ContainsKey(topicName))
            {
                switch (transport)
                {
                case MessagingTransport.Queue:
                    adapter = new QueueAdapter <T>(ConnectionString, SubscriptionId, MessagesIn.AsObserver(),
                                                   batchSize, this);
                    break;

                case MessagingTransport.Topic:
                    adapter = new TopicAdapter <T>(ConnectionString, SubscriptionId, MessagesIn.AsObserver(),
                                                   batchSize, this, topicName);
                    break;

                default:
                    throw new InvalidOperationException(
                              $"The {nameof(MessagingTransport)} was extended and the use case on the {nameof(SetupMessageType)} switch wasn't.");
                }

                if (!ServiceBusAdapters.TryAdd(topicName, adapter))
                {
                    adapter.Dispose();
                    adapter = null;
                }
            }

            return((ServiceBusAdapter <T>)adapter ??
                   (ServiceBusAdapter <T>)ServiceBusAdapters[topicName]);
        }
        /// <summary>
        /// Set up the required receive pipeline, for the given message type, and return a reactive <see cref="T:System.IObservable`1" /> that you can subscribe to.
        /// </summary>
        /// <typeparam name="T">The type of the message returned by the observable.</typeparam>
        /// <param name="batchSize">The size of the batch when reading from a queue.</param>
        /// <returns>The typed <see cref="T:System.IObservable`1" /> that you subscribed to.</returns>
        /// <exception cref="InvalidOperationException">ReceiverConfig must be set to read messages.</exception>
        public IObservable <T> StartReceive <T>(int batchSize = 10) where T : class
        {
            // Ensure config is setup.
            if (Config.ReceiverConfig == null)
            {
                throw new InvalidOperationException("Receiver configuration must be set");
            }

            CreateIfNotExists();

            _receiverClient ??= SubscriberClient.CreateAsync(new SubscriptionName(Config.ProjectId, Config.ReceiverConfig.ReadFromErrorEntity
                    ? Config.ReceiverConfig.EntityDeadLetterName
                    : Config.ReceiverConfig.EntitySubscriptionName),
                                                             new SubscriberClient.ClientCreationSettings(credentials: GetCredentials())).GetAwaiter().GetResult();

            IObserver <T> messageIn = _messagesIn.AsObserver();

            _receiverClient.StartAsync((message, cancel) =>
            {
                if (!cancel.IsCancellationRequested)
                {
                    var typed = GetTypedMessageContent <T>(message);
                    messageIn.OnNext(typed);
                }

                return(Task.FromResult(SubscriberClient.Reply.Ack));
            });

            return(_messagesIn.OfType <T>());
        }
예제 #3
0
        /// <summary>
        /// Starts the receive.
        /// </summary>
        /// <typeparam name="T">Type of object to receive</typeparam>
        /// <param name="batchSize">Size of message batches to receive in a single call. If set to zero, uses the default batch size from config.</param>
        /// <returns>IObservable{T}.</returns>
        public IObservable <T> StartReceive <T>(int batchSize = 10) where T : class
        {
            IObserver <T> obs = MessagesIn.AsObserver();

            LockTimers.TryAdd(typeof(T), new Timer(t =>
            {
                if (!_inBatch)
                {
                    _inBatch = true;

                    try
                    {
                        var msgItems = GetMessages <T>(batchSize).GetAwaiter().GetResult();

                        foreach (var msg in msgItems)
                        {
                            obs.OnNext(msg.Body);
                        }
                    }
                    catch (Exception e)
                    {
                        obs.OnError(e);
                    }
                    finally
                    {
                        _inBatch = false;
                    }
                }
            }, null, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)));

            return(MessagesIn.OfType <T>().AsObservable());
        }
예제 #4
0
        /// <summary>
        /// Sets the messenger up for either sending or receiving a specific message of type <typeparamref name="T"/>.
        /// This will create the <see cref="Microsoft.ServiceBus.Messaging.QueueClient"/> but will not set it up for reading the queue.
        /// </summary>
        /// <typeparam name="T">The type of the message we are setting up.</typeparam>
        /// <returns>The message queue wrapper.</returns>
        internal MessageQueue <T> SetupMessageType <T>()
            where T : IMessage
        {
            lock (Gate)
            {
                if (!Queues.ContainsKey(typeof(T)))
                {
                    var queue = new MessageQueue <T>(ConnectionString, MessagesIn.AsObserver());
                    Queues.Add(typeof(T), queue);
                }
            }

            return((MessageQueue <T>)Queues[typeof(T)]);
        }
예제 #5
0
        /// <summary>
        /// Sets the messenger up for sending / receiving a specific message of type <typeparamref name="T" />.
        /// </summary>
        /// <typeparam name="T">The type of the message we are setting up.</typeparam>
        /// <returns>The message queue adapter.</returns>
        internal ServiceBusConnector <T> SetupConnectorType <T>() where T : class
        {
            Monitor.Enter(SetupGate);

            try
            {
                // If no adapter for this type already exists, then create an instance.
                if (!QueueConnectors.ContainsKey(typeof(T)))
                {
                    var queue = new ServiceBusConnector <T>(ConnectionManager, MessagesIn.AsObserver(), Logger);
                    QueueConnectors.TryAdd(typeof(T), queue);
                }

                return((ServiceBusConnector <T>)QueueConnectors[typeof(T)]);
            }
            finally
            {
                Monitor.Exit(SetupGate);
            }
        }