diff --git a/src/main/kotlin/com/jameskbride/localsns/models/Subscription.kt b/src/main/kotlin/com/jameskbride/localsns/models/Subscription.kt index 3cae91e..b38a0e1 100644 --- a/src/main/kotlin/com/jameskbride/localsns/models/Subscription.kt +++ b/src/main/kotlin/com/jameskbride/localsns/models/Subscription.kt @@ -23,4 +23,8 @@ data class Subscription( @JsonIgnore fun isRawMessageDelivery(): Boolean { return subscriptionAttributes.getOrDefault("RawMessageDelivery", "false") == "true" } + + @JsonIgnore fun xmlEncodeEndpointUrl(): String? { + return endpoint?.replace("&", "&") ?: endpoint + } } diff --git a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/getSubscriptionAttributesRoute.kt b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/getSubscriptionAttributesRoute.kt index b2d0736..0faaee5 100644 --- a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/getSubscriptionAttributesRoute.kt +++ b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/getSubscriptionAttributesRoute.kt @@ -37,7 +37,7 @@ var getSubscriptionAttributesRoute: (RoutingContext) -> Unit = route@{ ctx: Rout return@route } - val endpoint = URLEncoder.encode(subscription.endpoint.orEmpty(), "UTF-8") + val endpoint = subscription.xmlEncodeEndpointUrl() val mergedAttributes = mapOf( "SubscriptionArn" to subscription.arn, "TopicArn" to subscription.topicArn, diff --git a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsByTopicRoute.kt b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsByTopicRoute.kt index 4e70b44..fa52165 100644 --- a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsByTopicRoute.kt +++ b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsByTopicRoute.kt @@ -35,7 +35,7 @@ val listSubscriptionsByTopicRoute: (RoutingContext) -> Unit = route@{ ctx: Routi val sharedData = getSubscriptionsMap(vertx) val subscriptions = sharedData!!.getOrDefault(topicArn, listOf()) val subscriptionsContent = subscriptions.map { subscription -> - val endpoint = URLEncoder.encode(subscription.endpoint.orEmpty(), "UTF-8") + val endpoint = subscription.xmlEncodeEndpointUrl() """ ${subscription.owner} diff --git a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsRoute.kt b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsRoute.kt index d04116a..a2f7d55 100644 --- a/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsRoute.kt +++ b/src/main/kotlin/com/jameskbride/localsns/routes/subscriptions/listSubscriptionsRoute.kt @@ -11,7 +11,7 @@ val listSubscriptionsRoute: (RoutingContext) -> Unit = { ctx: RoutingContext -> val sharedData = getSubscriptionsMap(vertx) val subscriptions = sharedData!!.values.fold(listOf()) { acc, subscriptions -> acc + subscriptions } val subscriptionsContent = subscriptions.map{subscription -> - val endpoint = URLEncoder.encode(subscription.endpoint.orEmpty(), "UTF-8") + val endpoint = subscription.xmlEncodeEndpointUrl() """ ${subscription.owner} diff --git a/src/test/kotlin/com/jameskbride/localsns/GetSubscriptionAttributesRouteTest.kt b/src/test/kotlin/com/jameskbride/localsns/GetSubscriptionAttributesRouteTest.kt index 7f5d552..5c75dad 100644 --- a/src/test/kotlin/com/jameskbride/localsns/GetSubscriptionAttributesRouteTest.kt +++ b/src/test/kotlin/com/jameskbride/localsns/GetSubscriptionAttributesRouteTest.kt @@ -60,7 +60,7 @@ class GetSubscriptionAttributesRouteTest: BaseTest() { assertAttributeFound(entries, "SubscriptionArn", subscriptionArn) assertAttributeFound(entries, "TopicArn", topic.arn) assertAttributeFound(entries, "Owner", "") - assertAttributeFound(entries, "Endpoint", URLEncoder.encode(endpoint, "UTF-8")) + assertAttributeFound(entries, "Endpoint", endpoint) assertAttributeFound(entries, "Protocol", "sqs") assertAttributeFound(entries, "PendingConfirmation", "false") assertAttributeFound(entries, "SubscriptionPrincipal", "") diff --git a/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsByTopicRouteTest.kt b/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsByTopicRouteTest.kt index becb2c8..4693eb3 100644 --- a/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsByTopicRouteTest.kt +++ b/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsByTopicRouteTest.kt @@ -82,6 +82,11 @@ class ListSubscriptionsByTopicRouteTest: BaseTest() { .contains("sqs") && text.contains("queue1") }) + Assertions.assertTrue(members.any { + val text = it.text() + text.contains("Endpoint") && text.contains(endpoint1) + }) + //Only return subscriptions for the requested topic Assertions.assertTrue(members.none { val text = it.text() diff --git a/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsRouteTest.kt b/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsRouteTest.kt index 9c3d63e..bb88f06 100644 --- a/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsRouteTest.kt +++ b/src/test/kotlin/com/jameskbride/localsns/ListSubscriptionsRouteTest.kt @@ -6,6 +6,7 @@ import io.vertx.junit5.VertxExtension import io.vertx.junit5.VertxTestContext import org.jsoup.Jsoup import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -29,29 +30,45 @@ class ListSubscriptionsRouteTest: BaseTest() { @Test fun `it returns subscriptions when they exist `(testContext: VertxTestContext) { val topic = createTopicModel("topic1") - val endpoint1 = createSqsEndpoint("queue1") - val subscribeResponse1 = subscribe(topic.arn, endpoint1, "sqs") + val endpoint = createSqsEndpoint("queue1") + val subscribeResponse1 = subscribe(topic.arn, endpoint, "sqs") val subscription1Arn = getSubscriptionArnFromResponse(subscribeResponse1) - val topic2 = createTopicModel("topic2") - val endpoint2 = createSqsEndpoint("queue2") - val subscribeResponse2 = subscribe(topic2.arn, endpoint2, "lambda") - val subscription2Arn = getSubscriptionArnFromResponse(subscribeResponse2) - val response = listSubscriptions() Assertions.assertEquals(200, response.statusCode) val doc = Jsoup.parse(response.text) val members = doc.select("member").toList() - Assertions.assertTrue(members.any { + assertTrue(members.any { val text = it.text() text.contains(subscription1Arn) && text.contains(topic.arn) && text .contains("sqs") && text.contains("queue1") }) - Assertions.assertTrue(members.any { + assertTrue(members.any { + val text = it.text() + text.contains("Endpoint") && text.contains(endpoint) + }) + + testContext.completeNow() + } + + @Test + fun `it returns lambda subscriptions when they exist `(testContext: VertxTestContext) { + val topic = createTopicModel("topic2") + val endpoint = createSqsEndpoint("queue2") + val subscribeResponse2 = subscribe(topic.arn, endpoint, "lambda") + val subscription2Arn = getSubscriptionArnFromResponse(subscribeResponse2) + + val response = listSubscriptions() + Assertions.assertEquals(200, response.statusCode) + + val doc = Jsoup.parse(response.text) + val members = doc.select("member").toList() + + assertTrue(members.any { val text = it.text() - text.contains(subscription2Arn) && text.contains(topic2.arn) && text + text.contains(subscription2Arn) && text.contains(topic.arn) && text .contains("lambda") && text.contains("queue2") })