Esempio n. 1
0
        /// <summary>
        /// Creates <see cref="AzureBus{TAuthenticationToken}.NumberOfReceiversCount"/> <see cref="IMessageReceiver"/>.
        /// If flushing is required, any flushed <see cref="IMessageReceiver"/> has <see cref="ClientEntity.Close()"/> called on it first.
        /// </summary>
        /// <param name="manager">The <see cref="Manager"/>.</param>
        /// <param name="serviceBusReceivers">The receivers collection to place <see cref="IMessageReceiver"/> instances into.</param>
        /// <param name="topicName">The topic name.</param>
        /// <param name="topicSubscriptionName">The topic subscription name.</param>
#endif
#if NETSTANDARD2_0
        /// <summary>
        /// Creates <see cref="AzureBus{TAuthenticationToken}.NumberOfReceiversCount"/> <see cref="IMessageReceiver"/>.
        /// If flushing is required, any flushed <see cref="IMessageReceiver"/> has <see cref="ClientEntity.CloseAsync()"/> called on it first.
        /// </summary>
        /// <param name="manager">The <see cref="Manager"/>.</param>
        /// <param name="serviceBusReceivers">The receivers collection to place <see cref="IMessageReceiver"/> instances into.</param>
        /// <param name="topicName">The topic name.</param>
        /// <param name="topicSubscriptionName">The topic subscription name.</param>
#endif
        protected virtual void InstantiateReceiving(Manager manager, IDictionary <int, IMessageReceiver> serviceBusReceivers, string topicName, string topicSubscriptionName)
        {
            for (int i = 0; i < NumberOfReceiversCount; i++)
            {
#if NET452
                IMessageReceiver serviceBusReceiver = SubscriptionClient.CreateFromConnectionString(ConnectionString, topicName, topicSubscriptionName);
#endif
#if NETSTANDARD2_0
                IMessageReceiver serviceBusReceiver = new MessageReceiver(ConnectionString, EntityNameHelper.FormatSubscriptionPath(topicName, topicSubscriptionName));
#endif
                if (serviceBusReceivers.ContainsKey(i))
                {
                    serviceBusReceivers[i] = serviceBusReceiver;
                }
                else
                {
                    serviceBusReceivers.Add(i, serviceBusReceiver);
                }
            }
            // Remove any if the number has decreased
            for (int i = NumberOfReceiversCount; i < serviceBusReceivers.Count; i++)
            {
                IMessageReceiver serviceBusReceiver;
                if (serviceBusReceivers.TryGetValue(i, out serviceBusReceiver))
                {
#if NET452
                    serviceBusReceiver.Close();
#endif
#if NETSTANDARD2_0
                    serviceBusReceiver.CloseAsync().Wait(1500);
#endif
                }
                serviceBusReceivers.Remove(i);
            }
        }
Esempio n. 2
0
        protected override void ReceiveCommand(IMessageReceiver client, BrokeredMessage message)
#endif
        {
            try
            {
                Logger.LogDebug(string.Format("A command message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBodyAsString();
                ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
#if NET452
                string topicPath = serviceBusReceiver == null ? "UNKNOWN" : serviceBusReceiver.TopicPath;
#endif
#if NETSTANDARD2_0
                string topicPath = client == null ? "UNKNOWN" : client.Path;
#endif
                Logger.LogInfo($"A command message arrived from topic {topicPath} with the {message.MessageId} was of type {command.GetType().FullName}.");

                Type commandType = command.GetType();

                string targetQueueName = commandType.FullName;

                try
                {
                    object rsn = commandType.GetProperty("Rsn").GetValue(command, null);
                    targetQueueName = string.Format("{0}.{1}", targetQueueName, rsn);
                }
                catch
                {
                    Logger.LogDebug(string.Format("A command message arrived with the id '{0}' was of type {1} but with no Rsn property.", message.MessageId, commandType));
                    // Do nothing if there is no rsn. Just use command type name
                }

                CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                EnqueueCommand(targetQueueName, command);

                // remove the original message from the incoming queue
#if NET452
                message.Complete();
#endif
#if NETSTANDARD2_0
                client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif

                Logger.LogDebug(string.Format("A command message arrived and was processed with the id '{0}'.", message.MessageId));
            }
            catch (Exception exception)
            {
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("A command message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
#if NET452
                message.Abandon();
#endif
#if NETSTANDARD2_0
                client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
            }
        }
Esempio n. 3
0
        public async Task GetMessageAsync(CancellationToken cancellationToken, string Label, Func <BrokeredMessage, Task> callback, OnMessageOptions options)
        {
            var receiverFactory = MessagingFactory.CreateFromConnectionString(ServiceBusConnectionString);

            subscriptionClient = receiverFactory.CreateSubscriptionClient(topicName, subscriptionname);
            var doneReceiving = new TaskCompletionSource <bool>();

            cancellationToken.Register(
                async() =>
            {
                await subscriptionClient.CloseAsync();
                await receiverFactory.CloseAsync();
                doneReceiving.SetResult(true);
            });

            subscriptionClient.OnMessageAsync(callback, options);
            await doneReceiving.Task;
        }
Esempio n. 4
0
        public async Task GetMessageAsync(CancellationToken cancellationToken, string Label)
        {
            var receiverFactory = MessagingFactory.CreateFromConnectionString(ServiceBusConnectionString);

            subscriptionClient = receiverFactory.CreateSubscriptionClient(topicName, subscriptionname);

            var doneReceiving = new TaskCompletionSource <bool>();

            cancellationToken.Register(
                async() =>
            {
                await subscriptionClient.CloseAsync();
                await receiverFactory.CloseAsync();
                doneReceiving.SetResult(true);
            });



            subscriptionClient.OnMessageAsync(
                async message =>
            {
                if (message.Label != null &&
                    message.ContentType != null &&
                    message.Label.Equals(Label, StringComparison.InvariantCultureIgnoreCase) &&
                    message.ContentType.Equals("application/json", StringComparison.InvariantCultureIgnoreCase))
                {
                    var body = message.GetBody <Stream>();
                    Message  = JsonConvert.DeserializeObject(new StreamReader(body, true).ReadToEnd()).ToString();
                    message.Complete();
                }
                else
                {
                    await message.DeadLetterAsync("ProcessingError", "Don't know what to do with this message");
                }
            },
                new OnMessageOptions {
                AutoComplete = false, MaxConcurrentCalls = 1
            });

            await doneReceiving.Task;
        }
Esempio n. 5
0
        protected virtual void ReceiveEvent(IMessageReceiver client, BrokeredMessage message)
#endif
        {
            DateTimeOffset startedAt     = DateTimeOffset.UtcNow;
            Stopwatch      mainStopWatch = Stopwatch.StartNew();
            string         responseCode  = "200";
            // Null means it was skipped
            bool?              wasSuccessfull            = true;
            string             telemetryName             = string.Format("Cqrs/Handle/Event/{0}", message.MessageId);
            ISingleSignOnToken authenticationToken       = null;
            Guid?              guidAuthenticationToken   = null;
            string             stringAuthenticationToken = null;
            int?intAuthenticationToken = null;

            IDictionary <string, string> telemetryProperties = ExtractTelemetryProperties(message, "Azure/Servicebus");

            TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles++, telemetryProperties);
            var brokeredMessageRenewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                    string messageBody = message.GetBodyAsString();

                    IEvent <TAuthenticationToken> @event = AzureBusHelper.ReceiveEvent(messageBody, ReceiveEvent,
                                                                                       string.Format("id '{0}'", message.MessageId),
                                                                                       ExtractSignature(message),
                                                                                       SigningTokenConfigurationKey,
                                                                                       () =>
                    {
                        wasSuccessfull = null;
                        telemetryName  = string.Format("Cqrs/Handle/Event/Skipped/{0}", message.MessageId);
                        responseCode   = "204";
                        // Remove message from queue
                        try
                        {
#if NET452
                            message.Complete();
#endif
#if NETSTANDARD2_0
                            client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                        }
                        catch (AggregateException aggregateException)
                        {
                            if (aggregateException.InnerException is MessageLockLostException)
                            {
                                throw new MessageLockLostException(string.Format("The lock supplied for the skipped event message '{0}' is invalid.", message.MessageId), aggregateException.InnerException);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (MessageLockLostException exception)
                        {
                            throw new MessageLockLostException(string.Format("The lock supplied for the skipped event message '{0}' is invalid.", message.MessageId), exception);
                        }
                        Logger.LogDebug(string.Format("An event message arrived with the id '{0}' but processing was skipped due to event settings.", message.MessageId));
                        TelemetryHelper.TrackEvent("Cqrs/Handle/Event/Skipped", telemetryProperties);
                    },
                                                                                       () =>
                    {
#if NET452
                        AzureBusHelper.RefreshLock(brokeredMessageRenewCancellationTokenSource, message, "event");
#endif
#if NETSTANDARD2_0
                        AzureBusHelper.RefreshLock(client, brokeredMessageRenewCancellationTokenSource, message, "event");
#endif
                    }
                                                                                       );

                    if (wasSuccessfull != null)
                    {
                        if (@event != null)
                        {
                            telemetryName       = string.Format("{0}/{1}/{2}", @event.GetType().FullName, @event.GetIdentity(), @event.Id);
                            authenticationToken = @event.AuthenticationToken as ISingleSignOnToken;
                            if (AuthenticationTokenIsGuid)
                            {
                                guidAuthenticationToken = @event.AuthenticationToken as Guid?;
                            }
                            if (AuthenticationTokenIsString)
                            {
                                stringAuthenticationToken = @event.AuthenticationToken as string;
                            }
                            if (AuthenticationTokenIsInt)
                            {
                                intAuthenticationToken = @event.AuthenticationToken as int?;
                            }

                            var telemeteredMessage = @event as ITelemeteredMessage;
                            if (telemeteredMessage != null)
                            {
                                telemetryName = telemeteredMessage.TelemetryName;
                            }

                            telemetryName = string.Format("Cqrs/Handle/Event/{0}", telemetryName);
                        }
                        // Remove message from queue
                        try
                        {
#if NET452
                            message.Complete();
#endif
#if NETSTANDARD2_0
                            client.CompleteAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                        }
                        catch (AggregateException aggregateException)
                        {
                            if (aggregateException.InnerException is MessageLockLostException)
                            {
                                throw new MessageLockLostException(string.Format("The lock supplied for event '{0}' of type {1} is invalid.", @event.Id, @event.GetType().Name), aggregateException.InnerException);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (MessageLockLostException exception)
                        {
                            throw new MessageLockLostException(string.Format("The lock supplied for event '{0}' of type {1} is invalid.", @event.Id, @event.GetType().Name), exception);
                        }
                    }
                    Logger.LogDebug(string.Format("An event message arrived and was processed with the id '{0}'.", message.MessageId));

                    IList <IEvent <TAuthenticationToken> > events;
                    if (EventWaits.TryGetValue(@event.CorrelationId, out events))
                    {
                        events.Add(@event);
                    }
                }
                catch (AggregateException aggregateException)
                {
                    throw aggregateException.InnerException;
                }
            }
            catch (MessageLockLostException exception)
            {
                IDictionary <string, string> subTelemetryProperties = new Dictionary <string, string>(telemetryProperties);
                subTelemetryProperties.Add("TimeTaken", mainStopWatch.Elapsed.ToString());
                TelemetryHelper.TrackException(exception, null, subTelemetryProperties);
                if (ThrowExceptionOnReceiverMessageLockLostExceptionDuringComplete)
                {
                    Logger.LogError(exception.Message, exception: exception);
                    // Indicates a problem, unlock message in queue
#if NET452
                    message.Abandon();
#endif
#if NETSTANDARD2_0
                    client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                    wasSuccessfull = false;
                }
                else
                {
                    Logger.LogWarning(exception.Message, exception: exception);
                    try
                    {
#if NET452
                        message.DeadLetter("LockLostButHandled", "The message was handled but the lock was lost.");
#endif
#if NETSTANDARD2_0
                        client.DeadLetterAsync(message.SystemProperties.LockToken, "LockLostButHandled", "The message was handled but the lock was lost.").Wait(1500);
#endif
                    }
                    catch (Exception)
                    {
                        // Oh well, move on.
#if NET452
                        message.Abandon();
#endif
#if NETSTANDARD2_0
                        client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                    }
                }
                responseCode = "599";
            }
            catch (UnAuthorisedMessageReceivedException exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but was not authorised.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("UnAuthorisedMessageReceivedException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "UnAuthorisedMessageReceivedException", exception.Message).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "401";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            catch (NoHandlersRegisteredException exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but no handlers were found to process it.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("NoHandlersRegisteredException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "NoHandlersRegisteredException", exception.Message).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "501";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            catch (NoHandlerRegisteredException exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but no handler was found to process it.", message.MessageId), exception: exception);
#if NET452
                message.DeadLetter("NoHandlerRegisteredException", exception.Message);
#endif
#if NETSTANDARD2_0
                client.DeadLetterAsync(message.SystemProperties.LockToken, "NoHandlerRegisteredException", exception.Message).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "501";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            catch (Exception exception)
            {
                TelemetryHelper.TrackException(exception, null, telemetryProperties);
                // Indicates a problem, unlock message in queue
                Logger.LogError(string.Format("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
#if NET452
                message.Abandon();
#endif
#if NETSTANDARD2_0
                client.AbandonAsync(message.SystemProperties.LockToken).Wait(1500);
#endif
                wasSuccessfull = false;
                responseCode   = "500";
                telemetryProperties.Add("ExceptionType", exception.GetType().FullName);
                telemetryProperties.Add("ExceptionMessage", exception.Message);
            }
            finally
            {
                // Cancel the lock of renewing the task
                brokeredMessageRenewCancellationTokenSource.Cancel();
                TelemetryHelper.TrackMetric("Cqrs/Handle/Event", CurrentHandles--, telemetryProperties);

                mainStopWatch.Stop();
                if (guidAuthenticationToken != null)
                {
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        guidAuthenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );
                }
                else if (intAuthenticationToken != null)
                {
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        intAuthenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );
                }
                else if (stringAuthenticationToken != null)
                {
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        stringAuthenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );
                }
                else
                {
                    TelemetryHelper.TrackRequest
                    (
                        telemetryName,
                        authenticationToken,
                        startedAt,
                        mainStopWatch.Elapsed,
                        responseCode,
                        wasSuccessfull == null || wasSuccessfull.Value,
                        telemetryProperties
                    );
                }

                TelemetryHelper.Flush();
            }
        }
        /// <summary>
        /// Deserialises and processes the <paramref name="messageBody"/> received from the network through the provided <paramref name="receiveCommandHandler"/>.
        /// </summary>
        /// <param name="serviceBusReceiver">The channel the message was received on.</param>
        /// <param name="messageBody">A serialised <see cref="IMessage"/>.</param>
        /// <param name="receiveCommandHandler">The handler method that will process the <see cref="ICommand{TAuthenticationToken}"/>.</param>
        /// <param name="messageId">The network id of the <see cref="IMessage"/>.</param>
        /// <param name="signature">The signature of the <see cref="IMessage"/>.</param>
        /// <param name="signingTokenConfigurationKey">The configuration key for the signing token as used by <see cref="IConfigurationManager"/>.</param>
        /// <param name="skippedAction">The <see cref="Action"/> to call when the <see cref="ICommand{TAuthenticationToken}"/> is being skipped.</param>
        /// <param name="lockRefreshAction">The <see cref="Action"/> to call to refresh the network lock.</param>
        /// <returns>The <see cref="ICommand{TAuthenticationToken}"/> that was processed.</returns>
#endif
#if NETSTANDARD2_0
        /// <summary>
        /// Deserialises and processes the <paramref name="messageBody"/> received from the network through the provided <paramref name="receiveCommandHandler"/>.
        /// </summary>
        /// <param name="client">The channel the message was received on.</param>
        /// <param name="messageBody">A serialised <see cref="IMessage"/>.</param>
        /// <param name="receiveCommandHandler">The handler method that will process the <see cref="ICommand{TAuthenticationToken}"/>.</param>
        /// <param name="messageId">The network id of the <see cref="IMessage"/>.</param>
        /// <param name="signature">The signature of the <see cref="IMessage"/>.</param>
        /// <param name="signingTokenConfigurationKey">The configuration key for the signing token as used by <see cref="IConfigurationManager"/>.</param>
        /// <param name="skippedAction">The <see cref="Action"/> to call when the <see cref="ICommand{TAuthenticationToken}"/> is being skipped.</param>
        /// <param name="lockRefreshAction">The <see cref="Action"/> to call to refresh the network lock.</param>
        /// <returns>The <see cref="ICommand{TAuthenticationToken}"/> that was processed.</returns>
#endif
        public virtual ICommand <TAuthenticationToken> ReceiveCommand(
#if NET452
            IMessageReceiver serviceBusReceiver
Esempio n. 7
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the command bus.
        /// </summary>
#if NET452
        protected virtual void ReceiveCommand(IMessageReceiver serviceBusReceiver, BrokeredMessage message)
Esempio n. 8
0
 public StockListenerService(SubscriptionClient subscriptionClient, StockItemHandler handler)
 {
     _subscriptionClient = subscriptionClient;
     _handler            = handler;
 }
Esempio n. 9
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the event bus, identifies a key and queues it accordingly.
        /// </summary>
#if NET452
        protected override void ReceiveEvent(IMessageReceiver serviceBusReceiver, BrokeredMessage message)
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the event bus.
        /// </summary>
#if NET452
        protected virtual void ReceiveEvent(IMessageReceiver serviceBusReceiver, BrokeredMessage message)