All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.http4k.connect.amazon.sqs.endpoints.kt Maven / Gradle / Ivy
package org.http4k.connect.amazon.sqs
import dev.forkhandles.result4k.Failure
import dev.forkhandles.result4k.Success
import dev.forkhandles.result4k.asResultOr
import dev.forkhandles.result4k.map
import dev.forkhandles.result4k.peek
import org.http4k.connect.amazon.AmazonRestfulFake
import org.http4k.connect.amazon.RestfulError
import org.http4k.connect.amazon.core.model.ARN
import org.http4k.connect.amazon.core.model.AwsAccount
import org.http4k.connect.amazon.core.model.Region
import org.http4k.connect.amazon.sqs.action.CreateQueue
import org.http4k.connect.amazon.sqs.action.CreatedQueue
import org.http4k.connect.amazon.sqs.action.DeleteMessageBatch
import org.http4k.connect.amazon.sqs.action.DeleteMessageBatchResponse
import org.http4k.connect.amazon.sqs.action.DeleteMessageBatchResultEntry
import org.http4k.connect.amazon.sqs.action.DeleteMessageData
import org.http4k.connect.amazon.sqs.action.DeleteQueue
import org.http4k.connect.amazon.sqs.action.GetQueueAttributes
import org.http4k.connect.amazon.sqs.action.ListQueues
import org.http4k.connect.amazon.sqs.action.ListQueuesResponse
import org.http4k.connect.amazon.sqs.action.QueueAttributes
import org.http4k.connect.amazon.sqs.action.ReceiveMessage
import org.http4k.connect.amazon.sqs.action.ReceiveMessageResponse
import org.http4k.connect.amazon.sqs.action.SendMessage
import org.http4k.connect.amazon.sqs.action.SendMessageBatch
import org.http4k.connect.amazon.sqs.action.SendMessageBatchResponse
import org.http4k.connect.amazon.sqs.action.SendMessageBatchResultEntry
import org.http4k.connect.amazon.sqs.action.SentMessage
import org.http4k.connect.amazon.sqs.model.ReceiptHandle
import org.http4k.connect.amazon.sqs.model.SQSMessage
import org.http4k.connect.amazon.sqs.model.SQSMessageId
import org.http4k.connect.storage.Storage
import org.http4k.core.Method
import org.http4k.core.Request
import org.http4k.core.Status
import org.http4k.core.Uri
import org.http4k.core.extend
import org.http4k.routing.asRouter
import org.http4k.routing.bind
import java.util.UUID
private fun forAction(name: String) = { r: Request ->
r.method == Method.POST && r.header("X-Amz-Target") == "AmazonSQS.$name"
}.asRouter()
fun AmazonRestfulFake.createQueue(queues: Storage>, awsAccount: AwsAccount) =
forAction("CreateQueue") bind route { data ->
if (queues.keySet(data.QueueName.value).isEmpty()) {
queues[data.QueueName.value] = listOf()
}
Success(CreatedQueue(uri.extend(Uri.of("/$awsAccount/${data.QueueName}"))))
}
fun AmazonRestfulFake.getQueueAttributes(queues: Storage>) =
forAction("GetQueueAttributes") bind route { data ->
val name = data.queueUrl.queueName()
queues[name]
.asResultOr { queueNotFound(name) }
.map { queue ->
QueueAttributes(mapOf(
"LastModifiedTimestamp" to "0",
"CreatedTimestamp" to "0",
"MessageRetentionPeriod" to "0",
"DelaySeconds" to "0",
"ReceiveMessageWaitTimeSeconds" to "0",
"MaximumMessageSize" to "0",
"VisibilityTimeout" to "0",
"ApproximateNumberOfMessagesDelayed" to queue.size.toString(),
"ApproximateNumberOfMessages" to queue.size.toString(),
"ApproximateNumberOfMessagesNotVisible" to "0"
))
}
}
fun AmazonRestfulFake.listQueues(region: Region, account: AwsAccount, queues: Storage>) =
forAction("ListQueues") bind route {
// TODO handle pagination
Success(ListQueuesResponse(
NextToken = null,
QueueUrls = queues.keySet().map { Uri.of("https://sqs.${region}.amazonaws.com/${account}/$it") }
))
}
fun AmazonRestfulFake.deleteQueue(queues: Storage>) =
forAction("DeleteQueue") bind route { data ->
val queueName = data.QueueUrl.queueName()
queues[queueName]
.asResultOr { queueNotFound(queueName) }
.peek { queues -= queueName }
.map { }
}
fun AmazonRestfulFake.sendMessage(queues: Storage>) =
forAction("SendMessage") bind route { data ->
val name = data.queueUrl.queueName()
queues[name].asResultOr { queueNotFound(name) }.map { queue ->
val messageId = SQSMessageId.of(UUID.randomUUID().toString())
val receiptHandle = ReceiptHandle.of(UUID.randomUUID().toString())
val sqsMessage = SQSMessage(messageId, data.messageBody, data.messageBody.md5(), receiptHandle, data.messageAttributes.orEmpty())
queues[name] = queue + sqsMessage
SentMessage(
MessageId = sqsMessage.messageId,
SequenceNumber = null,
MD5OfMessageBody = sqsMessage.md5OfBody,
MD5OfMessageAttributes = if (sqsMessage.attributes.isNotEmpty()) sqsMessage.md5OfAttributes() else null
)
}
}
fun AmazonRestfulFake.sendMessageBatch(queues: Storage>) =
forAction("SendMessageBatch") bind route fn@{ data ->
val queueName = data.queueUrl.queueName()
val queue = queues[queueName] ?: return@fn Failure(queueNotFound(queueName))
val results = data.entries.map { entry ->
val message = SQSMessage(
messageId = SQSMessageId.of(UUID.randomUUID().toString()),
body = entry.MessageBody,
md5OfBody = entry.MessageBody.md5(),
receiptHandle = ReceiptHandle.of(UUID.randomUUID().toString()),
messageAttributes = entry.MessageAttributes.orEmpty()
)
val result = SendMessageBatchResultEntry(
Id = entry.Id,
MessageId = message.messageId,
MD5OfMessageBody = message.md5OfBody(),
MD5OfMessageAttributes = if (message.attributes.isNotEmpty()) message.md5OfAttributes() else null
)
message to result
}
queues[queueName] = queue + results.map { it.first }
Success(SendMessageBatchResponse(
Failed = null,
Successful = results.map { it.second }
))
}
fun AmazonRestfulFake.receiveMessage(queues: Storage>) =
forAction("ReceiveMessage") bind route { data ->
val name = data.queueUrl.queueName()
queues[name].asResultOr { queueNotFound(name) }.map { queue ->
val messagesToSend = data.maxNumberOfMessages?.let { queue.take(it) } ?: queue
ReceiveMessageResponse(messagesToSend)
}
}
fun AmazonRestfulFake.deleteMessage(queues: Storage>) =
forAction("DeleteMessage") bind route { data ->
val name = data.QueueUrl.queueName()
val receiptHandle = data.ReceiptHandle
queues[name]
.asResultOr { queueNotFound(name) }
.peek { queue -> queues[name] = queue.filterNot { it.receiptHandle == receiptHandle } }
.map { }
}
fun AmazonRestfulFake.deleteMessageBatch(queues: Storage>) =
forAction("DeleteMessageBatch") bind route fn@{ data ->
val queueName = data.queueUrl.queueName()
val queue = queues[queueName] ?: return@fn Failure(queueNotFound(queueName))
val toDelete = data.entries.mapNotNull { entry ->
queue.find { it.receiptHandle == entry.ReceiptHandle }
}.toSet()
queues[queueName] = queue - toDelete
Success(DeleteMessageBatchResponse(
Failed = emptyList(),
Successful = toDelete.map {
DeleteMessageBatchResultEntry(it.messageId)
}
))
}
private fun Uri.queueName() = toString().queueName()
private fun String.queueName() = substring(lastIndexOf('/') + 1)
private fun AmazonRestfulFake.queueNotFound(name: String): RestfulError {
val resourceArn = ARN.of(awsService, region, accountId, name)
val message = "Queue $name not found"
return RestfulError(Status(404, ""), message, resourceArn, "queue")
}