public static TransportMessage ToTransportMessage(this SqsTransportMessage sqsTransportMessage, IAmazonS3 amazonS3, SqsConnectionConfiguration connectionConfiguration) { var messageId = sqsTransportMessage.Headers[Headers.MessageId]; var result = new TransportMessage(messageId, sqsTransportMessage.Headers); if (!string.IsNullOrEmpty(sqsTransportMessage.S3BodyKey)) { var s3GetResponse = amazonS3.GetObject(connectionConfiguration.S3BucketForLargeMessages, sqsTransportMessage.S3BodyKey); result.Body = new byte[s3GetResponse.ResponseStream.Length]; s3GetResponse.ResponseStream.Read(result.Body, 0, result.Body.Length); } else { result.Body = Convert.FromBase64String(sqsTransportMessage.Body); } result.TimeToBeReceived = sqsTransportMessage.TimeToBeReceived; if (sqsTransportMessage.ReplyToAddress != null) { result.Headers[Headers.ReplyToAddress] = sqsTransportMessage.ReplyToAddress.ToString(); } return(result); }
public void Send(TransportMessage message, SendOptions sendOptions) { try { var sqsTransportMessage = new SqsTransportMessage(message, sendOptions); var serializedMessage = JsonConvert.SerializeObject(sqsTransportMessage); if (serializedMessage.Length > 256*1024) { if (string.IsNullOrEmpty(ConnectionConfiguration.S3BucketForLargeMessages)) { throw new InvalidOperationException("Cannot send large message because no S3 bucket was configured. Add an S3 bucket name to your configuration."); } var key = ConnectionConfiguration.S3KeyPrefix + "/" + message.Id; S3Client.PutObject(new Amazon.S3.Model.PutObjectRequest { BucketName = ConnectionConfiguration.S3BucketForLargeMessages, InputStream = new MemoryStream(message.Body), Key = key }); sqsTransportMessage.S3BodyKey = key; sqsTransportMessage.Body = String.Empty; serializedMessage = JsonConvert.SerializeObject(sqsTransportMessage); } try { SendMessage(serializedMessage, sendOptions); } catch (QueueDoesNotExistException) { QueueCreator.CreateQueueIfNecessary(sendOptions.Destination, ""); SendMessage(serializedMessage, sendOptions); } } catch (Exception e) { Logger.Error("Exception from Send.", e); throw; } }
public static async Task <IncomingMessage> ToIncomingMessage(this SqsTransportMessage sqsTransportMessage, IAmazonS3 amazonS3, SqsConnectionConfiguration connectionConfiguration, CancellationToken cancellationToken) { var messageId = sqsTransportMessage.Headers[Headers.MessageId]; byte[] body; if (!string.IsNullOrEmpty(sqsTransportMessage.S3BodyKey)) { var s3GetResponse = await amazonS3.GetObjectAsync(connectionConfiguration.S3BucketForLargeMessages, sqsTransportMessage.S3BodyKey, cancellationToken).ConfigureAwait(false); body = new byte[s3GetResponse.ResponseStream.Length]; using (BufferedStream bufferedStream = new BufferedStream(s3GetResponse.ResponseStream)) { int count; int transferred = 0; const int maxChunkSize = 8 * 1024; int bytesToRead = Math.Min(maxChunkSize, body.Length - transferred); while ((count = await bufferedStream.ReadAsync(body, transferred, bytesToRead, cancellationToken).ConfigureAwait(false)) > 0) { transferred += count; bytesToRead = Math.Min(maxChunkSize, body.Length - transferred); } } } else { body = Convert.FromBase64String(sqsTransportMessage.Body); } return(new IncomingMessage(messageId, sqsTransportMessage.Headers, body)); }
private void DeleteMessage(IAmazonSQS sqs, IAmazonS3 s3, Message message, SqsTransportMessage sqsTransportMessage, TransportMessage transportMessage) { sqs.DeleteMessage(_queueUrl, message.ReceiptHandle); if (!String.IsNullOrEmpty(sqsTransportMessage.S3BodyKey)) { // Delete the S3 body asynchronously. // We don't really care too much if this call succeeds or fails - if it fails, // the S3 bucket lifecycle configuration will eventually delete the message anyway. // So, we can get better performance by not waiting around for this call to finish. var s3DeleteTask = s3.DeleteObjectAsync( new DeleteObjectRequest { BucketName = ConnectionConfiguration.S3BucketForLargeMessages, Key = ConnectionConfiguration.S3KeyPrefix + transportMessage.Id }); s3DeleteTask.ContinueWith(t => { if (t.Exception != null) { // If deleting the message body from S3 fails, we don't // want the exception to make its way through to the _endProcessMessage below, // as the message has been successfully processed and deleted from the SQS queue // and effectively doesn't exist anymore. // It doesn't really matter, as S3 is configured to delete message body data // automatically after a certain period of time. Logger.Warn("Couldn't delete message body from S3. Message body data will be aged out at a later time.", t.Exception); } }); } }