/// <inheritdoc /> protected override async Task <IEnumerable <QueuedMessage> > GetPendingMessages(CancellationToken cancellationToken = new CancellationToken()) { var pendingMessages = new List <QueuedMessage>(); var files = _directory.EnumerateFiles("*.pmsg"); foreach (var file in files) { try { var messageFile = new MessageFile(file); var message = await messageFile.ReadMessage(cancellationToken); if (message.IsEncrypted() && _messageEncryptionService != null) { message = await _messageEncryptionService.Decrypt(message); } var principal = await _securityTokenService.NullSafeValidate(message.Headers.SecurityToken); var queuedMessage = new QueuedMessage(message, principal); pendingMessages.Add(queuedMessage); } catch (Exception ex) { DiagnosticService.Emit(new FilesystemEventBuilder(this, FilesystemEventType.MessageFileFormatError) { Detail = "Error reading previously queued message file; skipping", Path = file.FullName, Exception = ex }.Build()); } } return(pendingMessages); }
private async void MoveToDeadLetterDirectory(FileInfo file) { try { var deadLetter = new FileInfo(Path.Combine(_deadLetterDirectory.FullName, file.Name)); file.MoveTo(deadLetter.FullName); await DiagnosticService.EmitAsync( new FilesystemEventBuilder(this, DiagnosticEventType.DeadLetter) { Detail = "Message file moved to dead letter directory", Queue = QueueName, Path = deadLetter.FullName }.Build()); } catch (Exception ex) { DiagnosticService.Emit( new FilesystemEventBuilder(this, DiagnosticEventType.DeadLetterError) { Detail = "Error moving message file to dead letter directory", Queue = QueueName, Path = file.FullName, Exception = ex }.Build()); } }
/// <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()); }
private void MoveToDeadLetterDirectory(QueuedMessage queuedMessage) { string pattern = ""; try { var message = queuedMessage.Message; var headers = message.Headers; pattern = headers.MessageId + "*.pmsg"; var matchingFiles = _directory.EnumerateFiles(pattern); foreach (var matchingFile in matchingFiles) { MoveToDeadLetterDirectory(matchingFile); } } catch (Exception ex) { DiagnosticService.Emit( new FilesystemEventBuilder(this, DiagnosticEventType.DeadLetterError) { Detail = "Error moving message file(s) to dead letter directory", Queue = QueueName, Path = Path.Combine(_directory.FullName, pattern), Exception = ex }.Build()); } }
/// <inheritdoc /> /// <summary> /// Returns messages in the queue that are pending /// </summary> /// <param name="cancellationToken">(Optional) A token provided by the caller that can /// be used by the caller to request cancellation of the fetch operation</param> /// <returns>Returns the set of pending messages in the queue</returns> protected override async Task <IEnumerable <QueuedMessage> > GetPendingMessages(CancellationToken cancellationToken = default(CancellationToken)) { var fb = Builders <QueuedMessageDocument> .Filter; var filter = fb.Eq(qm => qm.Queue, (string)QueueName) & fb.Eq(qm => qm.State, QueuedMessageState.Pending); var existingMessages = await _queuedMessages.Find(filter).ToListAsync(cancellationToken); var queuedMessages = new List <QueuedMessage>(); foreach (var queuedMessage in existingMessages) { try { var messageHeaders = new MessageHeaders(queuedMessage.Headers); var principal = await _securityTokenService.NullSafeValidate(messageHeaders.SecurityToken); var message = new Message(messageHeaders, queuedMessage.Content); if (message.IsEncrypted() && _messageEncryptionService != null) { message = await _messageEncryptionService.Decrypt(message); } message = message.WithoutSecurityToken(); queuedMessages.Add(new QueuedMessage(message, principal, queuedMessage.Attempts)); } catch (Exception ex) { DiagnosticService.Emit(new MongoDBEventBuilder(this, MongoDBEventType.MessageDocumentFormatError) { Detail = "Error reading previously queued message document ID " + queuedMessage.Id + "; skipping", CollectionName = _queuedMessages.CollectionNamespace.CollectionName, DatabaseName = _queuedMessages.Database.DatabaseNamespace.DatabaseName, Exception = ex }.Build()); } } return(queuedMessages); }