Skip to content

Commit a9f7b66

Browse files
authored
fix BinaryValue message attribute containing base64 string value (#952)
1 parent fc1397c commit a9f7b66

File tree

3 files changed

+37
-29
lines changed

3 files changed

+37
-29
lines changed

core/src/main/scala/org/elasticmq/MessageAttribute.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ case class BinaryMessageAttribute(binaryValue: Array[Byte], override val customT
2929

3030
def asBase64: String = Base64.getEncoder.encodeToString(binaryValue)
3131
}
32+
3233
object BinaryMessageAttribute {
3334
def fromBase64(base64Str: String, customType: Option[String] = None): BinaryMessageAttribute =
3435
BinaryMessageAttribute(
3536
binaryValue = Base64.getDecoder.decode(base64Str),
3637
customType = customType
3738
)
3839

39-
def fromByteBuffer(byteBuffer: ByteBuffer, customType: Option[String] = None) =
40+
def fromByteBuffer(byteBuffer: ByteBuffer, customType: Option[String] = None): BinaryMessageAttribute =
4041
BinaryMessageAttribute(
4142
binaryValue = {
4243
byteBuffer.clear()

rest/rest-sqs-testing-amazon-java-sdk/src/test/scala/org/elasticmq/rest/sqs/AmazonJavaSdkV2TestSuite.scala

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ package org.elasticmq.rest.sqs
22

33
import org.elasticmq.{BinaryMessageAttribute, MessageAttribute, NumberMessageAttribute, StringMessageAttribute}
44
import org.scalatest.matchers.should.Matchers
5+
import software.amazon.awssdk.core.SdkBytes
6+
import software.amazon.awssdk.services.sqs.model.{GetQueueUrlRequest => AwsSdkGetQueueUrlRequest, _}
57

68
import scala.collection.JavaConverters._
7-
import software.amazon.awssdk.core.SdkBytes
8-
import software.amazon.awssdk.services.sqs.model._
9-
import software.amazon.awssdk.services.sqs.model.{GetQueueUrlRequest => AwsSdkGetQueueUrlRequest}
109

1110
class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication with Matchers {
1211

@@ -46,8 +45,7 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
4645
Map(
4746
"red" -> StringMessageAttribute("fish"),
4847
"blue" -> StringMessageAttribute("cat"),
49-
// affected by https://github.com/softwaremill/elasticmq/issues/946
50-
// "green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
48+
"green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
5149
"yellow" -> NumberMessageAttribute("1234567890"),
5250
"orange" -> NumberMessageAttribute("0987654321", Some("custom"))
5351
)
@@ -60,8 +58,7 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
6058
Map(
6159
"red" -> StringMessageAttribute("fish"),
6260
"blue" -> StringMessageAttribute("cat"),
63-
// affected by https://github.com/softwaremill/elasticmq/issues/946
64-
// "green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
61+
"green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
6562
"yellow" -> NumberMessageAttribute("1234567890"),
6663
"orange" -> NumberMessageAttribute("0987654321", Some("custom"))
6764
),
@@ -75,8 +72,7 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
7572
Map(
7673
"red" -> StringMessageAttribute("fish"),
7774
"blue" -> StringMessageAttribute("cat"),
78-
// affected by https://github.com/softwaremill/elasticmq/issues/946
79-
// "green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
75+
"green" -> BinaryMessageAttribute("dog".getBytes("UTF-8")),
8076
"yellow" -> NumberMessageAttribute("1234567890"),
8177
"orange" -> NumberMessageAttribute("0987654321", Some("custom"))
8278
),
@@ -89,17 +85,17 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
8985
}
9086

9187
private def doTestSendAndReceiveMessageWithAttributes(
92-
content: String,
93-
messageAttributes: Map[String, MessageAttribute]
94-
): Unit = {
88+
content: String,
89+
messageAttributes: Map[String, MessageAttribute]
90+
): Unit = {
9591
doTestSendAndReceiveMessageWithAttributes(content, messageAttributes, List("All"))
9692
}
9793

9894
private def doTestSendAndReceiveMessageWithAttributes(
99-
content: String,
100-
messageAttributes: Map[String, MessageAttribute],
101-
requestedAttributes: List[String]
102-
): Unit = {
95+
content: String,
96+
messageAttributes: Map[String, MessageAttribute],
97+
requestedAttributes: List[String]
98+
): Unit = {
10399
// Given
104100
val queue = clientV2.createQueue(CreateQueueRequest.builder().queueName("testQueue1").build())
105101

@@ -148,11 +144,11 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
148144
}
149145

150146
private def checkMessageAttributesMatchRequestedAttributes(
151-
messageAttributes: Map[String, MessageAttribute],
152-
requestedAttributes: List[String],
153-
sendMessageRequest: SendMessageRequest,
154-
message: Message
155-
) = {
147+
messageAttributes: Map[String, MessageAttribute],
148+
requestedAttributes: List[String],
149+
sendMessageRequest: SendMessageRequest,
150+
message: Message
151+
) = {
156152
val filteredSendMessageAttr =
157153
filterBasedOnRequestedAttributes(requestedAttributes, sendMessageRequest.messageAttributes.asScala.toMap).asJava
158154
val filteredMessageAttributes = filterBasedOnRequestedAttributes(requestedAttributes, messageAttributes)
@@ -182,9 +178,9 @@ class AmazonJavaSdkV2TestSuite extends SqsClientServerWithSdkV2Communication wit
182178
}
183179

184180
private def filterBasedOnRequestedAttributes[T](
185-
requestedAttributes: List[String],
186-
messageAttributes: Map[String, T]
187-
): Map[String, T] = {
181+
requestedAttributes: List[String],
182+
messageAttributes: Map[String, T]
183+
): Map[String, T] = {
188184
if (requestedAttributes.contains("All")) {
189185
messageAttributes
190186
} else {

rest/rest-sqs/src/main/scala/org/elasticmq/rest/sqs/MessageAttributesSupport.scala

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package org.elasticmq.rest.sqs
22

33
import org.elasticmq.{BinaryMessageAttribute, MessageAttribute, NumberMessageAttribute, StringMessageAttribute}
44
import spray.json.DefaultJsonProtocol._
5-
import spray.json.{JsObject, JsString, JsValue, JsonReader, RootJsonFormat}
5+
import spray.json.{JsArray, JsObject, JsString, JsValue, JsonReader, RootJsonFormat}
66

77
trait MessageAttributesSupport {
88

@@ -18,20 +18,31 @@ trait MessageAttributesSupport {
1818
case StringMessageAttribute(value, customType) =>
1919
JsObject("DataType" -> JsString("String" + customTypeAsString(customType)), "StringValue" -> JsString(value))
2020
case msg: BinaryMessageAttribute =>
21-
JsObject("DataType" -> JsString("Binary" + customTypeAsString(msg.customType)), "BinaryValue" -> JsString(msg.asBase64))
21+
JsObject(
22+
"DataType" -> JsString("Binary" + customTypeAsString(msg.customType)),
23+
"BinaryValue" -> JsString(msg.asBase64)
24+
)
2225
}
2326

2427
override def read(json: JsValue): MessageAttribute = {
2528
val fields = json.asJsObject.fields
2629

30+
def pickFieldRaw(name: String) =
31+
fields.getOrElse(name, throw new SQSException(s"Field $name is required"))
32+
2733
def pickField[O: JsonReader](name: String) =
28-
fields.getOrElse(name, throw new SQSException(s"Field $name is required")).convertTo[O]
34+
pickFieldRaw(name).convertTo[O]
2935

3036
val dataType = pickField[String]("DataType")
3137
dataType match {
3238
case SomeNumber(ct) => NumberMessageAttribute(pickField[String]("StringValue"), customType(ct))
3339
case SomeString(ct) => StringMessageAttribute(pickField[String]("StringValue"), customType(ct))
34-
case SomeBinary(ct) => BinaryMessageAttribute(pickField[Array[Byte]]("BinaryValue"), customType(ct))
40+
case SomeBinary(ct) =>
41+
pickFieldRaw("BinaryValue") match {
42+
case arr: JsArray => BinaryMessageAttribute(arr.convertTo[Array[Byte]], customType(ct))
43+
case str: JsString => BinaryMessageAttribute.fromBase64(str.convertTo[String], customType(ct))
44+
case any: Any => throw new SQSException(s"Field BinaryValue has unsupported type $any")
45+
}
3546
case _ =>
3647
throw new Exception("Currently only handles String, Number and Binary typed attributes")
3748
}

0 commit comments

Comments
 (0)