Skip to content

Commit

Permalink
Fix getting text content in a transport tracker when compression is
Browse files Browse the repository at this point in the history
turned on
  • Loading branch information
anti-social committed Jul 10, 2023
1 parent 8a717a8 commit f612f3b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.kotest.matchers.maps.shouldContainExactly
import io.kotest.matchers.nulls.shouldBeNull
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldBeEmpty
import io.kotest.matchers.types.shouldBeInstanceOf

Expand Down Expand Up @@ -382,6 +383,83 @@ class ElasticsearchKtorTransportTests {
result shouldContainExactly mapOf("total_hits" to 21L)
}

@Test
fun trackersThatRequireTextContentWithGzipEncoder() = runTest {
val expectedContent = """{"query":{"match_all":{}}}"""
val client = ElasticsearchKtorTransport(
"http://example.com:9200",
MockEngine { request ->
request.method shouldBe HttpMethod.Get
if (isGzipSupported) {
request.headers["content-encoding"] shouldBe "gzip"
} else {
request.headers["content-encoding"].shouldBeNull()
}
request.url.encodedPath shouldBe "/products/_search"
request.body.contentType shouldBe ContentType.Application.Json

respond(
"""{"total_hits": 21}""",
headers = headersOf(
HttpHeaders.ContentType,
ContentType.Application.Json.withParameter("charset", "UTF-8").toString()
)
)
}
) {
gzipRequests = true
trackers = listOf(
{
object : Tracker {
override fun requiresTextContent(request: Request<*, *, *>): Boolean {
if (request.path.endsWith("/_search")) {
return true
}
return false
}

override suspend fun onRequest(request: PlainRequest) {
request.method shouldBe Method.GET
request.path shouldBe "products/_search"
request.contentType shouldBe "application/json"
if (isGzipSupported) {
request.contentEncoding shouldBe "gzip"
request.content shouldNotBe expectedContent.encodeToByteArray()
} else {
request.contentEncoding.shouldBeNull()
request.content shouldBe expectedContent.encodeToByteArray()
}
request.textContent shouldBe expectedContent
}

override suspend fun onResponse(responseResult: Result<PlainResponse>, duration: Duration) {
val response = responseResult.getOrThrow()
response.shouldBeInstanceOf<PlainResponse>()
response.statusCode shouldBe 200
response.contentType shouldBe "application/json"
response.content shouldBe """{"total_hits": 21}"""
duration shouldBeGreaterThan Duration.ZERO
}
}
}
)
}
val result = client.request(
ApiRequest(
Method.GET,
"products/_search",
body = JsonSerializer.obj {
obj("query") {
obj("match_all") {}
}
},
serde = JsonSerde,
processResponse = { resp -> resp.content.toMap() }
)
)
result shouldContainExactly mapOf("total_hits" to 21L)
}

@Test
fun trackersWithErrorResponse() = runTest {
val client = ElasticsearchKtorTransport(
Expand Down
1 change: 1 addition & 0 deletions elasticmagic-transport/api/elasticmagic-transport.api
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ public final class dev/evo/elasticmagic/transport/PreservingOriginGzipEncoder :
public fun <init> ()V
public fun append (Ljava/lang/CharSequence;)Ljava/lang/Appendable;
public fun toByteArray ()[B
public fun toString ()Ljava/lang/String;
}

public abstract class dev/evo/elasticmagic/transport/Request {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class PreservingOriginGzipEncoder : BaseGzipEncoder() {
override fun toByteArray(): ByteArray {
return gzipEncoder.toByteArray()
}

override fun toString(): String {
return identEncoder.toString()
}
}

sealed class Auth {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ abstract class ElasticsearchTestBase : TestBase() {
abstract val indexName: String

protected val debug = atomic(false)
// TODO: Also test against a transport with an enabled gzipRequests setting
protected val transport = ElasticsearchKtorTransport(
elasticUrl,
engine = httpEngine,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package dev.evo.elasticmagic

import dev.evo.elasticmagic.serde.kotlinx.JsonSerde
import dev.evo.elasticmagic.transport.ApiRequest
import dev.evo.elasticmagic.transport.CatRequest
import dev.evo.elasticmagic.transport.ElasticsearchException
import dev.evo.elasticmagic.transport.ElasticsearchKtorTransport
import dev.evo.elasticmagic.transport.Method
import dev.evo.elasticmagic.transport.TransportError

import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.shouldBe
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.types.shouldBeInstanceOf

Expand Down Expand Up @@ -55,4 +58,31 @@ class ElasticsearchTransportTests : TestBase() {
error.type shouldBe "illegal_argument_exception"
error.reason shouldContain "unknown_parameter"
}

@Test
fun compressedRequest() = runTest {
val transport = ElasticsearchKtorTransport(
elasticUrl,
engine = httpEngine,
) {
gzipRequests = true
if (elasticAuth != null) {
auth = elasticAuth
}
}
val result = transport.request(
ApiRequest(
Method.POST,
"_search",
parameters = mapOf("terminate_after" to listOf("1")),
body = JsonSerde.serializer.obj {
obj("query") {
obj("match_all") {}
}
},
serde = JsonSerde
)
)
result.long("took").shouldNotBeNull()
}
}

0 comments on commit f612f3b

Please sign in to comment.