public ProcessedMessage(ImportSuccessfullyProcessedMessage message)
        {
            UniqueMessageId = message.UniqueMessageId;            
            MessageMetadata = message.Metadata;
            Headers = message.PhysicalMessage.Headers;

            string processedAt;
            
            if (message.PhysicalMessage.Headers.TryGetValue(NServiceBus.Headers.ProcessingEnded, out processedAt))
            {
                ProcessedAt = DateTimeExtensions.ToUtcDateTime(processedAt);
            }
            else
            {
                ProcessedAt = DateTime.UtcNow;//best guess    
            }
        }
        public ProcessedMessage(ImportSuccessfullyProcessedMessage message)
        {
            UniqueMessageId = message.UniqueMessageId;
            MessageMetadata = message.Metadata;
            Headers         = message.PhysicalMessage.Headers;

            string processedAt;

            if (message.PhysicalMessage.Headers.TryGetValue(NServiceBus.Headers.ProcessingEnded, out processedAt))
            {
                ProcessedAt = DateTimeExtensions.ToUtcDateTime(processedAt);
            }
            else
            {
                ProcessedAt = DateTime.UtcNow;//best guess
            }
        }
        void InnerHandle(TransportMessage message)
        {
            var receivedMessage = new ImportSuccessfullyProcessedMessage(message);

            using (var childBuilder = Builder.CreateChildBuilder())
            {
                PipelineExecutor.CurrentContext.Set(childBuilder);

                foreach (var enricher in childBuilder.BuildAll<IEnrichImportedMessages>())
                {
                    enricher.Enrich(receivedMessage);
                }

                var logicalMessage = LogicalMessageFactory.Create(typeof(ImportSuccessfullyProcessedMessage),
                    receivedMessage);

                PipelineExecutor.InvokeLogicalMessagePipeline(logicalMessage);
            }

            if (Settings.ForwardAuditMessages == true)
            {
                Forwarder.Send(message, Settings.AuditLogQueue);
            }
        }
Example #4
0
        void InnerHandle(TransportMessage message)
        {
            var receivedMessage = new ImportSuccessfullyProcessedMessage(message);

            using (var childBuilder = Builder.CreateChildBuilder())
            {
                PipelineExecutor.CurrentContext.Set(childBuilder);

                foreach (var enricher in childBuilder.BuildAll <IEnrichImportedMessages>())
                {
                    enricher.Enrich(receivedMessage);
                }

                var logicalMessage = LogicalMessageFactory.Create(typeof(ImportSuccessfullyProcessedMessage),
                                                                  receivedMessage);

                PipelineExecutor.InvokeLogicalMessagePipeline(logicalMessage);
            }

            if (Settings.ForwardAuditMessages == true)
            {
                Forwarder.Send(message, Settings.AuditLogQueue);
            }
        }
        void RetryMessageImportById(string messageID)
        {
            // Try to get the batchErrorLock, if we can't then exit,
            // the message will trigger a retry next time on the next batch read.
            // Retrymessage may be fired again for the same message until the batches drain so this
            // prevents the message being processed twice,
            if (Monitor.TryEnter(batchErrorLockObj))
            {
                try
                {
                    Logger.DebugFormat("Drain stop running batch importers");
                    stopping = true;
                    var runningTasks = batchTaskTracker.Active();
                    Task.WaitAll(runningTasks);

                    var commitTransaction = false;
                    using (var queueReceiver = CreateReceiver())
                    using (var msmqTransaction = new MessageQueueTransaction())
                    {
                        msmqTransaction.Begin();
                        Logger.DebugFormat("Retry import of messageID - {0}", messageID);
                        try
                        {
                            Message message;
                            TransportMessage transportMessage;
                            try
                            {
                                message = queueReceiver.ReceiveById(messageID);
                                performanceCounters.MessageDequeued();
                            }
                            catch (Exception exception)
                            {
                                importFailuresHandler.FailedToReceive(exception); //logs and increments circuit breaker
                                return;
                            }

                            try
                            {
                                transportMessage = MsmqUtilities.Convert(message);
                            }
                            catch (Exception convertException)
                            {
                                importFailuresHandler.FailedToReceive(convertException); //logs and increments circuit breaker
                                serviceControlErrorQueue.Send(message, msmqTransaction); // Send unconvertable message to SC's ErrorQueue so it's not lost
                                commitTransaction = true; // Can't convert the messsage, so commit to get message out of the queue
                                return;
                            }

                            try
                            {
                                var importSuccessfullyProcessedMessage = new ImportSuccessfullyProcessedMessage(transportMessage);
                                foreach (var enricher in enrichers)
                                {
                                    enricher.Enrich(importSuccessfullyProcessedMessage);
                                }

                                using (var session = store.OpenSession())
                                {
                                    var auditMessage = new ProcessedMessage(importSuccessfullyProcessedMessage);
                                    session.Store(auditMessage);
                                    session.SaveChanges();
                                }
                                performanceCounters.MessageProcessed();

                                if (Settings.ForwardAuditMessages == true)
                                {
                                    Forwarder.Send(transportMessage, Settings.AuditLogQueue);
                                }

                                commitTransaction = true;
                            }
                            catch (Exception importException)
                            {
                                importFailuresHandler.Log(transportMessage, importException); //Logs and Writes failure transport message to Raven
                            }
                        }
                        finally
                        {
                            if (commitTransaction)
                            {
                                msmqTransaction.Commit();
                            }
                        }
                    }
                }
                finally
                {
                    Monitor.Exit(batchErrorLockObj);
                    //Restart Batch mode
                    stopping = false;
                    Logger.Debug("Ready to BeginPeek again");
                    queuePeeker.BeginPeek();
                }
            }
        }
        void BatchImporter()
        {
            String failedMessageID = null;
            try
            {
                Logger.DebugFormat("Batch job started", Task.CurrentId);

                var moreMessages = 0;

                using (var queueReceiver = CreateReceiver())
                {
                    do
                    {
                        if (moreMessages > RampUpConcurrencyMagicNumber)
                        {
                            if (TryStartNewBatchImporter())
                            {
                                Logger.Debug("We have too many messages, starting another batch importer");
                                moreMessages = 0; //Reset to 0 so we only ramp up once per BatchImporter
                            }
                        }

                        moreMessages++;

                        using (var msmqTransaction = new MessageQueueTransaction())
                        {
                            msmqTransaction.Begin();
                            using (var bulkInsert =store.BulkInsert(options:new BulkInsertOptions {CheckForUpdates = true}))
                            {
                                for (var idx = 0; idx < BatchSize; idx++)
                                {
                                    Message message = null;
                                    TransportMessage transportMessage;
                                    try
                                    {
                                        message = queueReceiver.Receive(receiveTimeout, msmqTransaction);
                                        performanceCounters.MessageDequeued();
                                        transportMessage = MsmqUtilities.Convert(message);
                                    }
                                    catch (MessageQueueException mqe)
                                    {
                                        if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                                        {
                                            moreMessages = 0;
                                            break;
                                        }
                                        throw;
                                    }
                                    catch (Exception)
                                    {
                                        if (message != null) {
                                            failedMessageID = message.Id;
                                        }
                                        throw;
                                    }

                                    try
                                    {
                                        var importSuccessfullyProcessedMessage = new ImportSuccessfullyProcessedMessage(transportMessage);
                                        foreach (var enricher in enrichers)
                                        {
                                            enricher.Enrich(importSuccessfullyProcessedMessage);
                                        }
                                        var auditMessage = new ProcessedMessage(importSuccessfullyProcessedMessage);
                                        bulkInsert.Store(auditMessage);
                                        performanceCounters.MessageProcessed();

                                        if (Settings.ForwardAuditMessages == true)
                                        {
                                            Forwarder.Send(transportMessage, Settings.AuditLogQueue);
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        if (message != null)
                                        {
                                            failedMessageID = message.Id;
                                        }
                                        throw;
                                    }
                                }
                            }
                            msmqTransaction.Commit();
                        }
                    } while (moreMessages > 0 && !stopping);
                }
                Logger.Debug("Stopping batch importer");
            }
            finally
            {
                if (!String.IsNullOrEmpty(failedMessageID))
                {
                    // Call RetryMessageImportById outside the Task as it checks for running tasks
                    ThreadPool.QueueUserWorkItem(state => RetryMessageImportById(failedMessageID));
                }
                countDownEvent.Decrement();
            }
        }
        void RetryMessageImportById(string messageID)
        {
            // Try to get the batchErrorLock, if we can't then exit,
            // the message will trigger a retry next time on the next batch read.
            // Retrymessage may be fired again for the same message until the batches drain so this
            // prevents the message being processed twice,
            if (Monitor.TryEnter(batchErrorLockObj))
            {
                try
                {
                    Logger.DebugFormat("Drain stop running batch importers");
                    stopping = true;
                    var runningTasks = batchTaskTracker.Active();
                    Task.WaitAll(runningTasks);

                    var commitTransaction = false;
                    using (var queueReceiver = CreateReceiver())
                        using (var msmqTransaction = new MessageQueueTransaction())
                        {
                            msmqTransaction.Begin();
                            Logger.DebugFormat("Retry import of messageID - {0}", messageID);
                            try
                            {
                                Message          message;
                                TransportMessage transportMessage;
                                try
                                {
                                    message = queueReceiver.ReceiveById(messageID);
                                    performanceCounters.MessageDequeued();
                                }
                                catch (Exception exception)
                                {
                                    importFailuresHandler.FailedToReceive(exception); //logs and increments circuit breaker
                                    return;
                                }

                                try
                                {
                                    transportMessage = MsmqUtilities.Convert(message);
                                }
                                catch (Exception convertException)
                                {
                                    importFailuresHandler.FailedToReceive(convertException); //logs and increments circuit breaker
                                    serviceControlErrorQueue.Send(message, msmqTransaction); // Send unconvertable message to SC's ErrorQueue so it's not lost
                                    commitTransaction = true;                                // Can't convert the messsage, so commit to get message out of the queue
                                    return;
                                }

                                try
                                {
                                    var importSuccessfullyProcessedMessage = new ImportSuccessfullyProcessedMessage(transportMessage);
                                    foreach (var enricher in enrichers)
                                    {
                                        enricher.Enrich(importSuccessfullyProcessedMessage);
                                    }

                                    using (var session = store.OpenSession())
                                    {
                                        var auditMessage = new ProcessedMessage(importSuccessfullyProcessedMessage);
                                        session.Store(auditMessage);
                                        session.SaveChanges();
                                    }
                                    performanceCounters.MessageProcessed();

                                    if (Settings.ForwardAuditMessages == true)
                                    {
                                        Forwarder.Send(transportMessage, Settings.AuditLogQueue);
                                    }

                                    commitTransaction = true;
                                }
                                catch (Exception importException)
                                {
                                    importFailuresHandler.Log(transportMessage, importException); //Logs and Writes failure transport message to Raven
                                }
                            }
                            finally
                            {
                                if (commitTransaction)
                                {
                                    msmqTransaction.Commit();
                                }
                            }
                        }
                }
                finally
                {
                    Monitor.Exit(batchErrorLockObj);
                    //Restart Batch mode
                    stopping = false;
                    Logger.Debug("Ready to BeginPeek again");
                    queuePeeker.BeginPeek();
                }
            }
        }
        void BatchImporter()
        {
            String failedMessageID = null;

            try
            {
                Logger.DebugFormat("Batch job started", Task.CurrentId);

                var moreMessages = 0;

                using (var queueReceiver = CreateReceiver())
                {
                    do
                    {
                        if (moreMessages > RampUpConcurrencyMagicNumber)
                        {
                            if (TryStartNewBatchImporter())
                            {
                                Logger.Debug("We have too many messages, starting another batch importer");
                                moreMessages = 0; //Reset to 0 so we only ramp up once per BatchImporter
                            }
                        }

                        moreMessages++;

                        using (var msmqTransaction = new MessageQueueTransaction())
                        {
                            msmqTransaction.Begin();
                            using (var bulkInsert = store.BulkInsert(options: new BulkInsertOptions {
                                CheckForUpdates = true
                            }))
                            {
                                for (var idx = 0; idx < BatchSize; idx++)
                                {
                                    Message          message = null;
                                    TransportMessage transportMessage;
                                    try
                                    {
                                        message = queueReceiver.Receive(receiveTimeout, msmqTransaction);
                                        performanceCounters.MessageDequeued();
                                        transportMessage = MsmqUtilities.Convert(message);
                                    }
                                    catch (MessageQueueException mqe)
                                    {
                                        if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                                        {
                                            moreMessages = 0;
                                            break;
                                        }
                                        throw;
                                    }
                                    catch (Exception)
                                    {
                                        if (message != null)
                                        {
                                            failedMessageID = message.Id;
                                        }
                                        throw;
                                    }

                                    try
                                    {
                                        var importSuccessfullyProcessedMessage = new ImportSuccessfullyProcessedMessage(transportMessage);
                                        foreach (var enricher in enrichers)
                                        {
                                            enricher.Enrich(importSuccessfullyProcessedMessage);
                                        }
                                        var auditMessage = new ProcessedMessage(importSuccessfullyProcessedMessage);
                                        bulkInsert.Store(auditMessage);
                                        performanceCounters.MessageProcessed();

                                        if (Settings.ForwardAuditMessages == true)
                                        {
                                            Forwarder.Send(transportMessage, Settings.AuditLogQueue);
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        if (message != null)
                                        {
                                            failedMessageID = message.Id;
                                        }
                                        throw;
                                    }
                                }
                            }
                            msmqTransaction.Commit();
                        }
                    } while (moreMessages > 0 && !stopping);
                }
                Logger.Debug("Stopping batch importer");
            }
            finally
            {
                if (!String.IsNullOrEmpty(failedMessageID))
                {
                    // Call RetryMessageImportById outside the Task as it checks for running tasks
                    ThreadPool.QueueUserWorkItem(state => RetryMessageImportById(failedMessageID));
                }
                countDownEvent.Decrement();
            }
        }