Skip to content

Commit 24c4be4

Browse files
authored
fix context path handling (#755)
1 parent 3ff4f1a commit 24c4be4

File tree

6 files changed

+79
-21
lines changed

6 files changed

+79
-21
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ case class NodeAddress(
77
contextPath: String = ""
88
) {
99
def hostAndPort: String = host + ":" + port
10-
def fullAddress: String = protocol + "://" + hostAndPort + contextPath
10+
def fullAddress: String = protocol + "://" + hostAndPort + suffix
1111
def isWildcard: Boolean = host == "*"
12+
def contextPathStripped: String = contextPath.stripPrefix("/").stripSuffix("/")
13+
def suffix = if (contextPath.isBlank) "" else "/" + contextPathStripped
1214
}

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,28 @@ class AmazonJavaSdkTestSuite extends SqsClientServerCommunication with Matchers
102102
client.listQueues().getQueueUrls.size() should be(0)
103103
}
104104

105-
test("should refer to queue via both URL formats") {
105+
test("should refer to queue via three URL formats") {
106106
// Given
107107
val queueUrl = client.createQueue(new CreateQueueRequest("lol")).getQueueUrl
108108

109109
// When
110-
val attributes2 = client
110+
val attributes1 = client
111111
.getQueueAttributes(new GetQueueAttributesRequest("http://localhost:9321/queue/lol").withAttributeNames("All"))
112112
.getAttributes
113-
val attributes1 = client
113+
val attributes2 = client
114114
.getQueueAttributes(
115115
new GetQueueAttributesRequest("http://localhost:9321/012345678900/lol").withAttributeNames("All")
116116
)
117117
.getAttributes
118+
val attributes3 = client
119+
.getQueueAttributes(
120+
new GetQueueAttributesRequest("http://localhost:9321/lol").withAttributeNames("All")
121+
)
122+
.getAttributes
118123

119124
// Then
120125
attributes1 should be(attributes2)
126+
attributes1 should be(attributes3)
121127
}
122128

123129
test("should get queue visibility timeout") {
@@ -255,7 +261,7 @@ class AmazonJavaSdkTestSuite extends SqsClientServerCommunication with Matchers
255261
Source.fromInputStream(res.getEntity.getContent).mkString should include("<Code>InvalidAction</Code>")
256262
}
257263

258-
test("should reply with 404 if request can't be recognized as any known route") {
264+
test("should reply with 400 and NonExistentQueue if path starts with invalid name") {
259265
// given
260266
val httpHost = new HttpHost("localhost", 9321)
261267
val req = new HttpPost()
@@ -268,8 +274,9 @@ class AmazonJavaSdkTestSuite extends SqsClientServerCommunication with Matchers
268274

269275
// then
270276
res.getStatusLine.getStatusCode shouldBe StatusCodes.BadRequest.intValue
271-
Source.fromInputStream(res.getEntity.getContent).mkString should include("<Code>Invalid request")
272-
277+
Source.fromInputStream(res.getEntity.getContent).mkString should include(
278+
"<Code>AWS.SimpleQueueService.NonExistentQueue"
279+
)
273280
}
274281

275282
test("should reply with a InvalidAction error when uknown action set") {
@@ -2048,13 +2055,6 @@ class AmazonJavaSdkTestSuite extends SqsClientServerCommunication with Matchers
20482055
}
20492056
}
20502057

2051-
test("should throw proper exception when referencing queue by name") {
2052-
val _ = client.createQueue(new CreateQueueRequest("testQueue1")).getQueueUrl
2053-
2054-
val ex = the[AmazonSQSException] thrownBy client.sendMessage(new SendMessageRequest("testQueue1", "Message 1"))
2055-
ex.getMessage should include("WrongURLFormatRejection(Provided only queueName instead of the full URL)")
2056-
}
2057-
20582058
test("should move message to dlq after exceeding maxReceiveCount") {
20592059

20602060
// given
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.elasticmq.rest.sqs
2+
3+
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
4+
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration
5+
import com.amazonaws.services.sqs.model.ReceiveMessageRequest
6+
import com.amazonaws.services.sqs.{AmazonSQS, AmazonSQSClientBuilder}
7+
import org.elasticmq.NodeAddress
8+
import org.elasticmq.util.Logging
9+
import org.scalatest.funsuite.AnyFunSuite
10+
import org.scalatest.matchers.should.Matchers
11+
import org.scalatest.{BeforeAndAfter, OptionValues}
12+
13+
import scala.collection.JavaConverters._
14+
import scala.util.Try
15+
16+
class CustomServerContextTest extends AnyFunSuite with BeforeAndAfter with Logging with Matchers with OptionValues {
17+
18+
var client: AmazonSQS = _
19+
var server: SQSRestServer = _
20+
21+
before {
22+
server = SQSRestServerBuilder
23+
.withPort(9321)
24+
.withServerAddress(NodeAddress(port = 9321, contextPath = "xyz"))
25+
.withAWSAccountId("123456789012")
26+
.withAWSRegion("elasticmq")
27+
.start()
28+
29+
client = AmazonSQSClientBuilder
30+
.standard()
31+
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("x", "x")))
32+
.withEndpointConfiguration(new EndpointConfiguration("http://localhost:9321/xyz", "us-east-1"))
33+
.build()
34+
}
35+
36+
after {
37+
client.shutdown()
38+
Try(server.stopAndWait())
39+
}
40+
41+
test("should create queue when context path is set") {
42+
val queue = client.createQueue("testQueue")
43+
queue.getQueueUrl should be("http://localhost:9321/xyz/123456789012/testQueue")
44+
}
45+
46+
test("should send and receive messages when context path is set") {
47+
val queue = client.createQueue("testQueue")
48+
49+
client.sendMessage("http://localhost:9321/xyz/123456789012/testQueue", "test msg1")
50+
client.sendMessage("http://localhost:9321/xyz/queue/testQueue", "test msg2")
51+
client.sendMessage("http://localhost:9321/xyz/abc/testQueue", "test msg3")
52+
client.sendMessage("http://localhost:9321/xyz/testQueue", "test msg4")
53+
54+
val message = client.receiveMessage(new ReceiveMessageRequest(queue.getQueueUrl).withMaxNumberOfMessages(10))
55+
56+
message.getMessages.asScala.map(_.getBody) should contain allOf ("test msg1", "test msg2", "test msg3", "test msg4")
57+
}
58+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ case class TheSQSRestServerBuilder(
167167
lazy val queueManagerActor = theQueueManagerActor
168168
lazy val sqsLimits = theLimits
169169
lazy val timeout = Timeout(21, TimeUnit.SECONDS) // see application.conf
170-
lazy val contextPath = serverAddress.contextPath
170+
lazy val contextPath = serverAddress.contextPathStripped
171171

172172
lazy val awsRegion: String = _awsRegion
173173
lazy val awsAccountId: String = _awsAccountId

rest/rest-sqs/src/main/scala/org/elasticmq/rest/sqs/directives/ElasticMQDirectives.scala

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

33
import akka.http.scaladsl.server.{Directives, Route}
4-
import org.elasticmq.rest.sqs.{ActorSystemModule, ContextPathModule, QueueManagerActorModule, QueueURLModule}
4+
import org.elasticmq.rest.sqs.{ActorSystemModule, ContextPathModule, QueueManagerActorModule}
55
import org.elasticmq.util.Logging
66

77
trait ElasticMQDirectives
@@ -24,7 +24,7 @@ trait ElasticMQDirectives
2424
private val validFifoParameterValueCharsRe = """^[a-zA-Z0-9!"#\$%&'\(\)\*\+,-\./:;<=>?@\[\\\]\^_`\{|\}~]{1,128}$""".r
2525

2626
def rootPath(body: Route): Route = {
27-
path("") {
27+
path(separateOnSlashes(contextPath) ~ Slash.?) {
2828
body
2929
}
3030
}

rest/rest-sqs/src/main/scala/org/elasticmq/rest/sqs/directives/QueueDirectives.scala

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

33
import akka.actor.ActorRef
44
import akka.http.scaladsl.model.Uri
5-
import akka.http.scaladsl.model.Uri.Path
65
import akka.http.scaladsl.server.PathMatcher.{Matched, Unmatched}
76
import akka.http.scaladsl.server._
87
import org.elasticmq.QueueData
98
import org.elasticmq.actor.reply._
109
import org.elasticmq.msg.{GetQueueData, LookupQueue}
11-
import org.elasticmq.rest.sqs.Constants._
1210
import org.elasticmq.rest.sqs._
1311

1412
trait QueueDirectives {
@@ -53,10 +51,10 @@ trait QueueDirectives {
5351
val pathDirective =
5452
if (contextPath.nonEmpty)
5553
pathPrefix(contextPath / accountIdRegex / Segment).tmap(_._2) |
56-
pathPrefix(contextPath / QueueUrlContext / Segment)
54+
pathPrefix(contextPath / Segment)
5755
else
5856
pathPrefix(accountIdRegex / Segment).tmap(_._2) |
59-
pathPrefix(QueueUrlContext / Segment)
57+
pathPrefix(Segment)
6058

6159
val queueNameDirective =
6260
checkOnlyOneSegmentInUri() |

0 commit comments

Comments
 (0)