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

org.elasticmq.rest.sqs.SendMessageBatchDirectives.scala Maven / Gradle / Ivy

The newest version!
package org.elasticmq.rest.sqs

import Constants._
import org.apache.pekko.http.scaladsl.server.Route
import org.elasticmq.MessageAttribute
import org.elasticmq.rest.sqs.Action.SendMessageBatch
import org.elasticmq.rest.sqs.ParametersUtil.ParametersParser
import org.elasticmq.rest.sqs.directives.ElasticMQDirectives
import org.elasticmq.rest.sqs.model.RequestPayload
import spray.json.DefaultJsonProtocol._
import spray.json.RootJsonFormat

import scala.xml.Elem

trait SendMessageBatchDirectives {
  this: ElasticMQDirectives
    with SendMessageDirectives
    with BatchRequestsModule
    with SQSLimitsModule
    with ResponseMarshaller =>

  def sendMessageBatch(p: RequestPayload)(implicit marshallerDependencies: MarshallerDependencies): Route = {
    p.action(SendMessageBatch) {
      val batch = p.as[BatchRequest[SendMessageBatchActionRequest]]
      queueActorAndDataFromQueueUrl(batch.QueueUrl) { (queueActor, queueData) =>
        verifyMessagesNotTooLong(batch.Entries)

        val resultsFuture = batchRequest(batch.Entries) { (messageData, id, index) =>
          validateMessageAttributes(messageData.MessageAttributes.getOrElse(Map.empty))

          val message =
            createMessage(messageData.toSendMessageActionRequest(batch.QueueUrl), queueData, index, p.xRayTracingHeader)

          doSendMessage(queueActor, message).map {
            case MessageSendOutcome(message, digest, messageAttributeDigest, systemMessageAttributeDigest) =>
              BatchMessageSendResponseEntry(
                id,
                messageAttributeDigest,
                digest,
                systemMessageAttributeDigest,
                message.id.id,
                None
              )
          }
        }
        complete(resultsFuture)
      }
    }
  }

  private def verifyMessagesNotTooLong(requests: List[SendMessageBatchActionRequest]): Unit = {
    val messageLengths = requests.map(_.MessageBody.length)
    verifyMessageNotTooLong(messageLengths.sum)
  }

  case class SendMessageBatchActionRequest(
      Id: String,
      DelaySeconds: Option[Long],
      MessageBody: String,
      MessageDeduplicationId: Option[String],
      MessageGroupId: Option[String],
      MessageSystemAttributes: Option[Map[String, MessageAttribute]],
      MessageAttributes: Option[Map[String, MessageAttribute]]
  ) extends BatchEntry {
    def toSendMessageActionRequest(queueUrl: String): SendMessageActionRequest = SendMessageActionRequest(
      DelaySeconds,
      MessageBody,
      MessageDeduplicationId,
      MessageGroupId,
      MessageSystemAttributes,
      MessageAttributes,
      queueUrl
    )
  }

  object SendMessageBatchActionRequest extends MessageAttributesSupport {

    implicit val jsonFormat: RootJsonFormat[SendMessageBatchActionRequest] = jsonFormat7(
      SendMessageBatchActionRequest.apply
    )

    implicit val queryFormat: BatchFlatParamsReader[SendMessageBatchActionRequest] = {
      new BatchFlatParamsReader[SendMessageBatchActionRequest] {
        override def read(params: Map[String, String]): SendMessageBatchActionRequest = {
          SendMessageBatchActionRequest(
            Id = requiredParameter(params)(IdSubParameter),
            DelaySeconds = params.parseOptionalLong(DelaySecondsParameter),
            MessageBody = requiredParameter(params)(MessageBodyParameter),
            MessageDeduplicationId = params.get(MessageDeduplicationIdParameter),
            MessageGroupId = params.get(MessageGroupIdParameter),
            MessageSystemAttributes = Some(getMessageAttributes("MessageSystemAttribute")(params)),
            MessageAttributes = Some(getMessageAttributes("MessageAttribute")(params))
          )
        }

        override def batchPrefix: String = "SendMessageBatchRequestEntry"
      }
    }
  }
}

case class BatchMessageSendResponseEntry(
    Id: String,
    MD5OfMessageAttributes: Option[String],
    MD5OfMessageBody: String,
    MD5OfMessageSystemAttributes: Option[String],
    MessageId: String,
    SequenceNumber: Option[Long]
)

object BatchMessageSendResponseEntry {
  implicit val format: RootJsonFormat[BatchMessageSendResponseEntry] = jsonFormat6(
    BatchMessageSendResponseEntry.apply
  )

  implicit val entryXmlSerializer: XmlSerializer[BatchMessageSendResponseEntry] = {
    new XmlSerializer[BatchMessageSendResponseEntry] {
      override def toXml(t: BatchMessageSendResponseEntry): Elem =
        
            {t.Id}
            {t.MD5OfMessageAttributes.map(d => {d}).getOrElse(())}
            {t.MD5OfMessageBody}
            {t.MessageId}
          
    }
  }

  implicit def batchXmlSerializer(implicit
      successSerializer: XmlSerializer[BatchMessageSendResponseEntry]
  ): XmlSerializer[BatchResponse[BatchMessageSendResponseEntry]] =
    new XmlSerializer[BatchResponse[BatchMessageSendResponseEntry]] {
      override def toXml(t: BatchResponse[BatchMessageSendResponseEntry]): Elem =
        
          
            {t.Successful.map(successSerializer.toXml) ++ t.Failed.toList.flatMap(_.map(XmlSerializer[Failed].toXml))}
          
          
            
              {EmptyRequestId}
            
          
        
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy