Пример #1
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
            }
        }
Пример #2
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the command bus, identifies a key and queues it accordingly.
        /// </summary>
        protected override void ReceiveCommand(BrokeredMessage message)
        {
            try
            {
                Logger.LogDebug(string.Format("A command message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
                Logger.LogInfo(string.Format("A command message arrived with the id '{0}' was of type {1}.", message.MessageId, 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
                message.Complete();

                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);
                message.Abandon();
            }
        }
Пример #3
0
        protected virtual void ReceiveCommand(BrokeredMessage message)
        {
            try
            {
                Logger.LogDebug(string.Format("A command message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
                Logger.LogInfo(string.Format("A command message arrived with the id '{0}' was of type {1}.", message.MessageId, command.GetType().FullName));

                ReceiveCommand(command);

                // Remove message from queue
                message.Complete();
                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);
                message.Abandon();
            }
        }
        /// <summary>
        /// Receives a <see cref="EventData"/> from the command bus, identifies a key and queues it accordingly.
        /// </summary>
        protected override void ReceiveCommand(PartitionContext context, EventData eventData)
        {
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
#if NET452
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
#if NET452
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());
#endif
#if NETSTANDARD2_0
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
#endif
                    ICommand <TAuthenticationToken> command = MessageSerialiser.DeserialiseCommand(messageBody);

                    CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
#if NET452
                    Logger.LogInfo(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, command.GetType().FullName));
#endif
#if NETSTANDARD2_0
                    Logger.LogInfo(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset, command.GetType().FullName));
#endif

                    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
                    {
#if NET452
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3} but with no Rsn property.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, commandType));
#endif
#if NETSTANDARD2_0
                        Logger.LogDebug(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3} but with no Rsn property.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset, commandType));
#endif
                        // 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
                    context.CheckpointAsync(eventData);

#if NET452
                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
#endif
#if NETSTANDARD2_0
                    Logger.LogDebug(string.Format("A command message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset));
#endif
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
#if NET452
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset), exception: exception);
#endif
#if NETSTANDARD2_0
                    Logger.LogError(string.Format("A command message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' but failed to be process.", eventData.SystemProperties.PartitionKey, eventData.SystemProperties.SequenceNumber, eventData.SystemProperties.Offset), exception: exception);
#endif

                    switch (i)
                    {
                    case 0:
                    case 1:
                        // 10 seconds
                        Thread.Sleep(10 * 1000);
                        break;

                    case 2:
                    case 3:
                        // 30 seconds
                        Thread.Sleep(30 * 1000);
                        break;

                    case 4:
                    case 5:
                    case 6:
                        // 1 minute
                        Thread.Sleep(60 * 1000);
                        break;

                    case 7:
                    case 8:
                    case 9:
                        // 3 minutes
                        Thread.Sleep(3 * 60 * 1000);
                        break;
                    }
                }
            }
            // Eventually just accept it
            context.CheckpointAsync(eventData);
        }
Пример #5
0
        public virtual ICommand <TAuthenticationToken> ReceiveCommand(string messageBody, Action <ICommand <TAuthenticationToken> > receiveCommandHandler, string messageId, Action skippedAction = null, Action lockRefreshAction = null)
        {
            ICommand <TAuthenticationToken> command;

            try
            {
                command = MessageSerialiser.DeserialiseCommand(messageBody);
            }
            catch (JsonSerializationException exception)
            {
                JsonSerializationException checkException = exception;
                bool safeToExit = false;
                do
                {
                    if (checkException.Message.StartsWith("Could not load assembly"))
                    {
                        safeToExit = true;
                        break;
                    }
                } while ((checkException = checkException.InnerException as JsonSerializationException) != null);
                if (safeToExit)
                {
                    const string pattern = @"(?<=^Error resolving type specified in JSON ').+?(?='\. Path '\$type')";
                    Match        match   = new Regex(pattern).Match(exception.Message);
                    if (match.Success)
                    {
                        string[] typeParts = match.Value.Split(',');
                        if (typeParts.Length == 2)
                        {
                            string classType  = typeParts[0];
                            bool   isRequired = BusHelper.IsEventRequired(string.Format("{0}.IsRequired", classType));

                            if (!isRequired)
                            {
                                if (skippedAction != null)
                                {
                                    skippedAction();
                                }
                                return(null);
                            }
                        }
                    }
                }
                throw;
            }

            string commandTypeName = command.GetType().FullName;

            CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
            Logger.LogInfo(string.Format("A command message arrived with the {0} was of type {1}.", messageId, commandTypeName));

            bool canRefresh;

            if (!ConfigurationManager.TryGetSetting(string.Format("{0}.ShouldRefresh", commandTypeName), out canRefresh))
            {
                canRefresh = false;
            }

            if (canRefresh)
            {
                if (lockRefreshAction == null)
                {
                    Logger.LogWarning(string.Format("A command message arrived with the {0} was of type {1} and was destined to support lock renewal, but no action was provided.", messageId, commandTypeName));
                }
                else
                {
                    lockRefreshAction();
                }
            }

            receiveCommandHandler(command);

            return(command);
        }
Пример #6
0
        protected virtual void ReceiveCommand(BrokeredMessage message)
        {
            try
            {
                Logger.LogDebug(string.Format("A command message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                ICommand <TAuthenticationToken> command;
                try
                {
                    command = MessageSerialiser.DeserialiseCommand(messageBody);
                }
                catch (JsonSerializationException exception)
                {
                    JsonSerializationException checkException = exception;
                    bool safeToExit = false;
                    do
                    {
                        if (checkException.Message.StartsWith("Could not load assembly"))
                        {
                            safeToExit = true;
                            break;
                        }
                    } while ((checkException = checkException.InnerException as JsonSerializationException) != null);
                    if (safeToExit)
                    {
                        const string pattern = @"(?<=^Error resolving type specified in JSON ').+?(?='\. Path '\$type')";
                        Match        match   = new Regex(pattern).Match(exception.Message);
                        if (match.Success)
                        {
                            string[] typeParts = match.Value.Split(',');
                            if (typeParts.Length == 2)
                            {
                                string classType  = typeParts[0];
                                bool   isRequired = BusHelper.IsEventRequired(string.Format("{0}.IsRequired", classType));

                                if (!isRequired)
                                {
                                    // Remove message from queue
                                    message.Complete();
                                    Logger.LogDebug(string.Format("A command message arrived with the id '{0}' but processing was skipped due to command settings.", message.MessageId));
                                    return;
                                }
                            }
                        }
                    }
                    throw;
                }

                CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
                Logger.LogInfo(string.Format("A command message arrived with the id '{0}' was of type {1}.", message.MessageId, command.GetType().FullName));

                ReceiveCommand(command);

                // Remove message from queue
                message.Complete();
                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);
                message.Abandon();
            }
        }
Пример #7
0
        /// <summary>
        /// Deserialises and processes the <paramref name="messageBody"/> received from the network through the provided <paramref name="receiveCommandHandler"/>.
        /// </summary>
        /// <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>
        public virtual ICommand <TAuthenticationToken> ReceiveCommand(string messageBody, Func <ICommand <TAuthenticationToken>, bool?> receiveCommandHandler, string messageId, string signature, string signingTokenConfigurationKey, Action skippedAction = null, Action lockRefreshAction = null)
        {
            ICommand <TAuthenticationToken> command;

            try
            {
                command = MessageSerialiser.DeserialiseCommand(messageBody);
            }
            catch (JsonSerializationException exception)
            {
                JsonSerializationException checkException = exception;
                bool safeToExit = false;
                do
                {
                    if (checkException.Message.StartsWith("Could not load assembly"))
                    {
                        safeToExit = true;
                        break;
                    }
                } while ((checkException = checkException.InnerException as JsonSerializationException) != null);
                if (safeToExit)
                {
                    const string pattern = @"(?<=^Error resolving type specified in JSON ').+?(?='\. Path '\$type')";
                    Match        match   = new Regex(pattern).Match(exception.Message);
                    if (match.Success)
                    {
                        string[] typeParts = match.Value.Split(',');
                        if (typeParts.Length == 2)
                        {
                            string classType  = typeParts[0];
                            bool   isRequired = BusHelper.IsEventRequired(string.Format("{0}.IsRequired", classType));

                            if (!isRequired)
                            {
                                if (skippedAction != null)
                                {
                                    skippedAction();
                                }
                                return(null);
                            }
                        }
                    }
                }
                throw;
            }

            string commandTypeName = command.GetType().FullName;

            CorrelationIdHelper.SetCorrelationId(command.CorrelationId);
            AuthenticationTokenHelper.SetAuthenticationToken(command.AuthenticationToken);
            string identifyMessage = null;
            var    identifiedEvent = command as ICommandWithIdentity <TAuthenticationToken>;

            if (identifiedEvent != null)
            {
                identifyMessage = string.Format(" for aggregate {0}", identifiedEvent.Rsn);
            }
            Logger.LogInfo(string.Format("A command message arrived with the {0} was of type {1}{2}.", messageId, commandTypeName, identifyMessage));

            VerifySignature(signingTokenConfigurationKey, signature, "A command", messageId, commandTypeName, identifyMessage, messageBody);
            bool canRefresh;

            if (!ConfigurationManager.TryGetSetting(string.Format("{0}.ShouldRefresh", commandTypeName), out canRefresh))
            {
                canRefresh = false;
            }

            if (canRefresh)
            {
                if (lockRefreshAction == null)
                {
                    Logger.LogWarning(string.Format("A command message arrived with the {0} was of type {1} and was destined to support lock renewal, but no action was provided.", messageId, commandTypeName));
                }
                else
                {
                    lockRefreshAction();
                }
            }

            // a false response means the action wasn't handled, but didn't throw an error, so we assume, by convention, that this means it was skipped.
            bool?result = receiveCommandHandler(command);

            if (result != null && !result.Value)
            {
                if (skippedAction != null)
                {
                    skippedAction();
                }
            }

            return(command);
        }