Exemple #1
0
        /// <summary>
        /// Updates a queued message in the database i.e. in response to an acknowledgement failure
        /// </summary>
        /// <param name="queuedMessage">The queued message to delete</param>
        /// <param name="abandoned">The date/time the message was abandoned (if applicable)</param>
        /// <param name="cancellationToken">(Optional) A cancellation token through which the
        ///     caller can request cancellation of the update operation</param>
        /// <returns>Returns a task that completes when the update operation completes</returns>
        protected virtual async Task UpdateQueuedMessage(QueuedMessage queuedMessage, DateTime?abandoned, CancellationToken cancellationToken = default(CancellationToken))
        {
            var connection = ConnectionProvider.GetConnection();

            try
            {
                var message        = queuedMessage.Message;
                var headers        = message.Headers;
                var commandBuilder = CommandBuilders.NewUpdateQueuedMessageCommandBuilder();
                commandBuilder.MessageId = headers.MessageId;
                commandBuilder.QueueName = QueueName;
                commandBuilder.Abandoned = abandoned;
                commandBuilder.Attempts  = queuedMessage.Attempts;

                using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
                {
                    using (var command = commandBuilder.BuildDbCommand(connection))
                    {
                        await command.ExecuteNonQueryAsync(cancellationToken);
                    }
                    scope.Complete();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(connection);
            }
        }
Exemple #2
0
        /// <inheritdoc />
        protected override async Task <IEnumerable <QueuedMessage> > GetPendingMessages(CancellationToken cancellationToken = default(CancellationToken))
        {
            var queuedMessages = new List <QueuedMessage>();
            var connection     = ConnectionProvider.GetConnection();

            try
            {
                var commandBuilder = CommandBuilders.NewSelectPendingMessagesCommandBuilder();
                commandBuilder.QueueName = QueueName;

                using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
                {
                    using (var command = commandBuilder.BuildDbCommand(connection))
                    {
                        using (var reader = await command.ExecuteReaderAsync(cancellationToken))
                        {
                            while (await reader.ReadAsync(cancellationToken))
                            {
                                try
                                {
                                    var record         = commandBuilder.BuildQueuedMessageRecord(reader);
                                    var messageContent = record.Content;
                                    var headers        = DeserializeHeaders(record.Headers);
                                    var message        = new Message(headers, messageContent);
                                    if (message.IsEncrypted() && MessageEncryptionService != null)
                                    {
                                        message = await MessageEncryptionService.Decrypt(message);
                                    }
#pragma warning disable 612
                                    var principal = await ResolvePrincipal(headers, record.SenderPrincipal);

#pragma warning restore 612
                                    message = message.WithoutSecurityToken();
                                    var attempts      = record.Attempts;
                                    var queuedMessage = new QueuedMessage(message, principal, attempts);
                                    queuedMessages.Add(queuedMessage);
                                }
                                catch (Exception ex)
                                {
                                    DiagnosticService.Emit(new SQLEventBuilder(this, SQLEventType.SQLMessageRecordFormatError)
                                    {
                                        Detail    = "Error reading previously queued message record; skipping",
                                        Exception = ex
                                    }.Build());
                                }
                            }
                        }
                    }
                    scope.Complete();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(connection);
            }

            // SQL calls are not async to avoid the need for TransactionAsyncFlowOption
            // and dependency on .NET 4.5.1 and later
            return(queuedMessages.AsEnumerable());
        }
        public RootCommand Build()
        {
            var builder = new CommandLineBuilder(
                new RootCommand(
                    "Simple communication system between local files and a given metabase server")
                )
                          .AddOption(ArgumentBuilder.SetServerOption(SessionCredentials))
                          .AddOption(ArgumentBuilder.SetUserNameOption(SessionCredentials))
                          .AddOption(ArgumentBuilder.SetPasswordOption(SessionCredentials))
                          .AddOption(ArgumentBuilder.SetVerbosityOption(LoggingLevelSwitch));

            CommandBuilders.ToList().ForEach(b => builder.AddCommand(b.Build()));
            return((RootCommand)builder.Command);
        }
Exemple #4
0
        /// <summary>
        /// Selects all dead messages from the SQL database
        /// </summary>
        /// <returns>Returns a task that completes when all records have been selected and whose
        /// result is the enumerable sequence of the selected records</returns>
        protected virtual async Task <IEnumerable <QueuedMessage> > GetDeadMessages(DateTime startDate, DateTime endDate, CancellationToken cancellationToken = new CancellationToken())
        {
            var queuedMessages = new List <QueuedMessage>();
            var connection     = ConnectionProvider.GetConnection();

            try
            {
                var commandBuilder = CommandBuilders.NewSelectDeadMessagesCommandBuilder();
                commandBuilder.QueueName = QueueName;
                commandBuilder.StartDate = startDate;
                commandBuilder.EndDate   = endDate;

                using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
                {
                    using (var command = commandBuilder.BuildDbCommand(connection))
                    {
                        using (var reader = await command.ExecuteReaderAsync(cancellationToken))
                        {
                            while (await reader.ReadAsync(cancellationToken))
                            {
                                var record         = commandBuilder.BuildQueuedMessageRecord(reader);
                                var messageContent = record.Content;
                                var headers        = DeserializeHeaders(record.Headers);
                                var message        = new Message(headers, messageContent);
#pragma warning disable 612
                                var principal = await ResolvePrincipal(headers, record.SenderPrincipal);

#pragma warning restore 612
                                var attempts      = record.Attempts;
                                var queuedMessage = new QueuedMessage(message, principal, attempts);
                                queuedMessages.Add(queuedMessage);
                            }
                        }
                    }
                    scope.Complete();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(connection);
            }
            return(queuedMessages.AsEnumerable());
        }
Exemple #5
0
        /// <summary>
        /// Inserts a new queued message into the database
        /// </summary>
        /// <param name="queuedMessage">The queued message to insert</param>
        /// <param name="cancellationToken">(Optional) A cancellation token through which the
        /// caller can request cancellation of the insert operation</param>
        /// <returns>Returns a task that completes when the insert operation completes</returns>
        protected virtual async Task InsertQueuedMessage(QueuedMessage queuedMessage, CancellationToken cancellationToken = default(CancellationToken))
        {
            var message       = queuedMessage.Message;
            var principal     = queuedMessage.Principal;
            var expires       = message.Headers.Expires;
            var connection    = ConnectionProvider.GetConnection();
            var securityToken = await SecurityTokenService.NullSafeIssue(principal, expires);

            var persistedMessage = message.WithSecurityToken(securityToken);

            if (MessageEncryptionService != null)
            {
                persistedMessage = await MessageEncryptionService.Encrypt(message);
            }
            try
            {
                var headers        = persistedMessage.Headers;
                var commandBuilder = CommandBuilders.NewInsertQueuedMessageCommandBuilder();
                commandBuilder.MessageId   = headers.MessageId;
                commandBuilder.QueueName   = QueueName;
                commandBuilder.Origination = headers.Origination?.ToString();
                commandBuilder.Destination = headers.Destination?.ToString();
                commandBuilder.ReplyTo     = headers.ReplyTo?.ToString();
                commandBuilder.Expires     = headers.Expires;
                commandBuilder.ContentType = headers.ContentType;
                commandBuilder.Headers     = SerializeHeaders(headers);
                commandBuilder.Content     = persistedMessage.Content;

                using (var scope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
                {
                    using (var command = commandBuilder.BuildDbCommand(connection))
                    {
                        await command.ExecuteNonQueryAsync(cancellationToken);
                    }
                    scope.Complete();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(connection);
            }
        }
        /// <inheritdoc />
        public override Task Init(CancellationToken cancellationToken = default(CancellationToken))
        {
            // A separate database file is created for each queue, so the object initialization
            // commands must be done once for each queue.

            var conection = ConnectionProvider.GetConnection();

            try
            {
                var commandBuilder = CommandBuilders.NewCreateObjectsCommandBuilder();
                using (var command = commandBuilder.BuildDbCommand(conection))
                {
                    command.ExecuteNonQuery();
                }
            }
            finally
            {
                ConnectionProvider.ReleaseConnection(conection);
            }
            return(base.Init(cancellationToken));
        }