All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlassian.aws.sqs.SQS.scala Maven / Gradle / Ivy

package io.atlassian.aws
package sqs

import com.amazonaws.services.sqs.model._
import kadai.Invalid
import scala.concurrent.duration._
import scalaz.{ NaturalTransformation, ~>, Functor, \/ }
import scalaz.std.list._
import scalaz.syntax.traverse._
import scalaz.syntax.id._
import scalaz.syntax.std.option._
import scala.collection.JavaConverters._

object SQS {
  import SQSAction._

  def createQueue(parameters: QueueParameters): SQSAction[QueueURL] =
    SQSAction.withClient {
      _.createQueue {
        val r = new CreateQueueRequest(parameters.name)
        r.withAttributes(parameters.attributes).withQueueName(parameters.name)
      } |> { res => QueueURL(res.getQueueUrl) }
    }

  def queueURL(name: String): SQSAction[QueueURL] =
    SQSAction.withClient { _.getQueueUrl(name) }.map { r => QueueURL(r.getQueueUrl) }

  def safeQueueURL(name: String): SQSAction[Option[QueueURL]] =
    queueURL(name).map { _.some }.handle {
      case Invalid.Err(e: QueueDoesNotExistException) => SQSAction.ok(None)
    }

  def deleteQueue(url: QueueURL): SQSAction[Unit] =
    SQSAction.withClient { c => c.deleteQueue(url.unwrap); () }

  def send[A: Marshaller](url: QueueURL, message: A, delay: Duration = 0.seconds): SQSAction[SendResult] =
    SQSAction.withClient {
      _.sendMessage(
        new SendMessageRequest()
          .withQueueUrl(url.unwrap)
          .withDelaySeconds(delay.toSeconds.toInt)
          .withMessageAttributes(Marshaller[A].headerFlattened(message).asJava)
          .withMessageBody(Marshaller[A].body(message))
      ) |> { res => SendResult(MessageId(res.getMessageId)) }
    }

  def receive[A: Unmarshaller](url: QueueURL, params: ReceiveMessageParameters = ReceiveMessageParameters()): SQSAction[List[ReceivedMessage[A]]] =
    SQSAction.withClient {
      _.receiveMessage {
        val r = new ReceiveMessageRequest(url.unwrap)
          .withMaxNumberOfMessages(params.numMessages)
          .withAttributeNames("All")
          .withMessageAttributeNames("All")
        params.visibilityTimeout.foreach { t => r.setVisibilityTimeout(t.toSeconds.toInt) }
        params.waitTime.foreach { t => r.setWaitTimeSeconds(t.toSeconds.toInt) }
        r
      }.getMessages.asScala.toList.map {
        m => Unmarshaller.receivedMessage[A].unmarshall(m).toOr.valueOr(ReceivedMessage.Invalid(m, _))
      }
    }

  def delete(url: QueueURL, handle: ReceiptHandle): SQSAction[Unit] =
    SQSAction.withClient { c =>
      c.deleteMessage(new DeleteMessageRequest().withQueueUrl(url.unwrap).withReceiptHandle(handle.unwrap))
      ()
    }

  def delete(url: QueueURL, handles: List[ReceiptHandle]): SQSAction[DeleteResult] = {

    def deleteBatch(batch: List[ReceiptHandle]): SQSAction[List[FailedDelete]] =
      SQSAction.withClient { client =>

        val batchWithId = batch.zipWithIndex.map { case (h, index) => index.toString -> h }
        val batchRequestEntries = batchWithId.map { case (index, h) => new DeleteMessageBatchRequestEntry(index, h.unwrap) }
        val idToHandle = batchWithId.toMap

        client.deleteMessageBatch(new DeleteMessageBatchRequest(url.unwrap)
          .withEntries(batchRequestEntries.asJava)).getFailed.asScala.map { entry =>
          FailedDelete(idToHandle.get(entry.getId), entry.getSenderFault, entry.getMessage)
        }.toList
      }

    handles.grouped(10).map { deleteBatch }.toList.sequence.map { _.flatten }.map { l => DeleteResult(handles, l) }
  }

  def changeVisibility(url: QueueURL, handle: ReceiptHandle, newVisibilityFromNow: Duration): SQSAction[Unit] = {
    SQSAction.withClient { c =>
      c.changeMessageVisibility(
        new ChangeMessageVisibilityRequest()
          .withQueueUrl(url.unwrap)
          .withReceiptHandle(handle.unwrap)
          .withVisibilityTimeout(newVisibilityFromNow.toSeconds.toInt)
      )
      ()
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy