Ejemplo n.º 1
0
        protected override void ReceiveEvent(IMessageReceiver client, BrokeredMessage message)
#endif
        {
            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBodyAsString();
                IEvent <TAuthenticationToken> @event = MessageSerialiser.DeserialiseEvent(messageBody);

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

                Type eventType = @event.GetType();

                string targetQueueName = eventType.FullName;

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

                CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                EnqueueEvent(targetQueueName, @event);

                // 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("An event 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("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
            }
        }
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the event bus, identifies a key and queues it accordingly.
        /// </summary>
        protected override void ReceiveEvent(BrokeredMessage message)
        {
            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                IEvent <TAuthenticationToken> @event = MessageSerialiser.DeserialiseEvent(messageBody);

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

                Type eventType = @event.GetType();

                string targetQueueName = eventType.FullName;

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

                CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                EnqueueEvent(targetQueueName, @event);

                // remove the original message from the incoming queue
                message.Complete();

                Logger.LogDebug(string.Format("An event 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("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
                message.Abandon();
            }
        }
Ejemplo n.º 3
0
        protected virtual void ReceiveEvent(BrokeredMessage message)
        {
            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                IEvent <TAuthenticationToken> @event = MessageSerialiser.DeserialiseEvent(messageBody);

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

                ReceiveEvent(@event);

                // Remove message from queue
                message.Complete();
                Logger.LogDebug(string.Format("An event 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("An event message arrived with the id '{0}' but failed to be process.", message.MessageId), exception: exception);
                message.Abandon();
            }
        }
Ejemplo n.º 4
0
        protected virtual void ReceiveEvent(BrokeredMessage message)
        {
            var brokeredMessageRenewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                Logger.LogDebug(string.Format("An event message arrived with the id '{0}'.", message.MessageId));
                string messageBody = message.GetBody <string>();
                IEvent <TAuthenticationToken> @event;

                try
                {
                    @event = MessageSerialiser.DeserialiseEvent(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("An event message arrived with the id '{0}' but processing was skipped due to event settings.", message.MessageId));
                                    return;
                                }
                            }
                        }
                    }
                    throw;
                }

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

                bool canRefresh;
                if (!ConfigurationManager.TryGetSetting(string.Format("{0}.ShouldRefresh", @event.GetType().FullName), out canRefresh))
                {
                    canRefresh = false;
                }

                if (canRefresh)
                {
                    Task.Factory.StartNew(() =>
                    {
                        while (!brokeredMessageRenewCancellationTokenSource.Token.IsCancellationRequested)
                        {
                            //Based on LockedUntilUtc property to determine if the lock expires soon
                            if (DateTime.UtcNow > message.LockedUntilUtc.AddSeconds(-10))
                            {
                                // If so, repeat the message
                                message.RenewLock();
                            }

                            Thread.Sleep(500);
                        }
                    }, brokeredMessageRenewCancellationTokenSource.Token);
                }

                ReceiveEvent(@event);

                // Remove message from queue
                message.Complete();
                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 (Exception exception)
            {
                // 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);
                message.Abandon();
            }
            finally
            {
                // Cancel the lock of renewing the task
                brokeredMessageRenewCancellationTokenSource.Cancel();
            }
        }
Ejemplo n.º 5
0
        public virtual IEvent <TAuthenticationToken> ReceiveEvent(string messageBody, Action <IEvent <TAuthenticationToken> > receiveEventHandler, string messageId, Action skippedAction = null, Action lockRefreshAction = null)
        {
            IEvent <TAuthenticationToken> @event;

            try
            {
                @event = MessageSerialiser.DeserialiseEvent(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 eventTypeName = @event.GetType().FullName;

            CorrelationIdHelper.SetCorrelationId(@event.CorrelationId);
            Logger.LogInfo(string.Format("An event message arrived with the {0} was of type {1}.", messageId, eventTypeName));

            bool canRefresh;

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

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

            receiveEventHandler(@event);

            return(@event);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Receives a <see cref="BrokeredMessage"/> from the event bus, identifies a key and queues it accordingly.
        /// </summary>
        protected override void ReceiveEvent(PartitionContext context, EventData eventData)
        {
            // Do a manual 10 try attempt with back-off
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Logger.LogDebug(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    string messageBody = Encoding.UTF8.GetString(eventData.GetBytes());
                    IEvent <TAuthenticationToken> @event = MessageSerialiser.DeserialiseEvent(messageBody);

                    CorrelationIdHelper.SetCorrelationId(@event.CorrelationId);
                    Logger.LogInfo(string.Format("An event message arrived with the partition key '{0}', sequence number '{1}' and offset '{2}' was of type {3}.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset, @event.GetType().FullName));

                    Type eventType = @event.GetType();

                    string targetQueueName = eventType.FullName;

                    try
                    {
                        object rsn = eventType.GetProperty("Rsn").GetValue(@event, null);
                        targetQueueName = string.Format("{0}.{1}", targetQueueName, rsn);
                    }
                    catch
                    {
                        Logger.LogDebug(string.Format("An event 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, eventType));
                        // Do nothing if there is no rsn. Just use @event type name
                    }

                    CreateQueueAndAttachListenerIfNotExist(targetQueueName);
                    EnqueueEvent(targetQueueName, @event);

                    // remove the original message from the incoming queue
                    context.CheckpointAsync(eventData);

                    Logger.LogDebug(string.Format("An event message arrived and was processed with the partition key '{0}', sequence number '{1}' and offset '{2}'.", eventData.PartitionKey, eventData.SequenceNumber, eventData.Offset));
                    return;
                }
                catch (Exception exception)
                {
                    // Indicates a problem, unlock message in queue
                    Logger.LogError(string.Format("An event 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);

                    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);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Deserialises and processes the <paramref name="messageBody"/> received from the network through the provided <paramref name="receiveEventHandler"/>.
        /// </summary>
        /// <param name="messageBody">A serialised <see cref="IMessage"/>.</param>
        /// <param name="receiveEventHandler">The handler method that will process the <see cref="IEvent{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="IEvent{TAuthenticationToken}"/> is being skipped.</param>
        /// <param name="lockRefreshAction">The <see cref="Action"/> to call to refresh the network lock.</param>
        /// <returns>The <see cref="IEvent{TAuthenticationToken}"/> that was processed.</returns>
        public virtual IEvent <TAuthenticationToken> ReceiveEvent(string messageBody, Func <IEvent <TAuthenticationToken>, bool?> receiveEventHandler, string messageId, string signature, string signingTokenConfigurationKey, Action skippedAction = null, Action lockRefreshAction = null)
        {
            IEvent <TAuthenticationToken> @event;

            try
            {
                @event = MessageSerialiser.DeserialiseEvent(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 eventTypeName = @event.GetType().FullName;

            CorrelationIdHelper.SetCorrelationId(@event.CorrelationId);
            AuthenticationTokenHelper.SetAuthenticationToken(@event.AuthenticationToken);
            object identifyMessage = null;
            var    identifiedEvent = @event as IEventWithIdentity <TAuthenticationToken>;

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

            VerifySignature(signingTokenConfigurationKey, signature, "An event", messageId, eventTypeName, identifyMessage, messageBody);
            bool canRefresh;

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

            if (canRefresh)
            {
                if (lockRefreshAction == null)
                {
                    Logger.LogWarning(string.Format("An event message arrived with the {0} was of type {1} and was destined to support lock renewal, but no action was provided.", messageId, eventTypeName));
                }
                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 = receiveEventHandler(@event);

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

            return(@event);
        }