Skip to content

Commit

Permalink
Improved elastic search captured certificate (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
osoykan committed Aug 16, 2023
1 parent c17ba77 commit da45c59
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 32 deletions.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ couchbase-client = { module = "com.couchbase.client:java-client", version.ref =
couchbase-client-metrics = { module = "com.couchbase.client:metrics-micrometer", version.ref = "couchbase-client-metrics" }
jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
jackson-arrow = { module = "io.arrow-kt:arrow-integrations-jackson-module", version = "0.14.1" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
ktor-server-host-common = { module = "io.ktor:ktor-server-host-common", version.ref = "ktor" }
Expand Down
1 change: 1 addition & 0 deletions lib/stove-testing-e2e-elasticsearch/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dependencies {
api(libs.elastic)
implementation(testLibs.testcontainers.elasticsearch)
implementation(libs.jackson.databind)
implementation(libs.jackson.arrow)
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.trendyol.stove.testing.e2e.elasticsearch

import arrow.core.getOrElse
import arrow.core.toOption
import arrow.core.*
import co.elastic.clients.elasticsearch.ElasticsearchClient
import co.elastic.clients.elasticsearch._types.Refresh
import co.elastic.clients.elasticsearch._types.query_dsl.Query
Expand All @@ -11,8 +10,6 @@ import co.elastic.clients.json.jackson.JacksonJsonpMapper
import co.elastic.clients.transport.rest_client.RestClientTransport
import com.trendyol.stove.functional.Try
import com.trendyol.stove.functional.recover
import com.trendyol.stove.testing.e2e.containers.ExposedCertificate
import com.trendyol.stove.testing.e2e.containers.NoCertificate
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.abstractions.*
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -53,13 +50,13 @@ class ElasticsearchSystem internal constructor(
}
}

private fun determineCertificate(): ExposedCertificate = when (context.options.containerOptions.disableSecurity) {
true -> NoCertificate
false -> ElasticsearchExposedCertificate(
context.container.caCertAsBytes().getOrElse { ByteArray(0) },
context.container.createSslContextFromCa()
)
}
private fun determineCertificate(): Option<ElasticsearchExposedCertificate> =
when (context.options.containerOptions.disableSecurity) {
true -> None
false -> ElasticsearchExposedCertificate(
context.container.caCertAsBytes().getOrElse { ByteArray(0) }
).apply { sslContext = context.container.createSslContextFromCa() }.some()
}

override suspend fun afterRun() {
esClient = createEsClient(exposedConfiguration)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.trendyol.stove.testing.e2e.elasticsearch

import arrow.core.getOrElse
import arrow.integrations.jackson.module.registerArrowModule
import com.trendyol.stove.testing.e2e.containers.withProvidedRegistry
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.ValidationDsl
Expand All @@ -21,6 +22,8 @@ fun TestSystem.withElasticsearch(
register<DefaultIndexMigrator> { options.defaultIndex.migrator }
}

options.objectMapper.registerArrowModule()

return withProvidedRegistry(
imageName = "elasticsearch/elasticsearch:${options.containerOptions.imageVersion}",
registry = options.containerOptions.registry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import arrow.core.None
import arrow.core.Option
import arrow.core.none
import co.elastic.clients.elasticsearch.ElasticsearchClient
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
import com.trendyol.stove.testing.e2e.containers.ExposedCertificate
import com.trendyol.stove.functional.Reflect
import com.trendyol.stove.testing.e2e.database.migrations.DatabaseMigration
import com.trendyol.stove.testing.e2e.database.migrations.MigrationCollection
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
Expand All @@ -16,6 +19,7 @@ import org.apache.http.client.config.RequestConfig
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder
import org.elasticsearch.client.RestClient
import org.testcontainers.elasticsearch.ElasticsearchContainer
import java.util.*
import javax.net.ssl.SSLContext
import kotlin.time.Duration.Companion.minutes

Expand All @@ -34,23 +38,63 @@ data class ElasticsearchSystemOptions(
* @see MigrationCollection
* @see DatabaseMigration
*/
fun migrations(migration: MigrationCollection<ElasticsearchClient>.() -> Unit): ElasticsearchSystemOptions = migration(
migrationCollection
).let {
this
}
fun migrations(migration: MigrationCollection<ElasticsearchClient>.() -> Unit): ElasticsearchSystemOptions =
migration(
migrationCollection
).let {
this
}
}

data class ElasticsearchExposedCertificate(
val bytes: ByteArray,
val sslContext: SSLContext
) : ExposedCertificate
val bytes: ByteArray
) {

@get:JsonIgnore
@set:JsonIgnore
var sslContext: SSLContext = SSLContext.getDefault()
internal set

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as ElasticsearchExposedCertificate

if (!bytes.contentEquals(other.bytes)) return false
if (sslContext != other.sslContext) return false

return true
}

override fun hashCode(): Int {
var result = bytes.contentHashCode()
result = 31 * result + sslContext.hashCode()
return result
}

companion object {
@JsonCreator
@JvmStatic
fun create(
@JsonProperty bytes: ByteArray
): ElasticsearchExposedCertificate {
val container = ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:latest")
Reflect(container) {
on<Optional<ByteArray>>("caCertAsBytes").then(Optional.of(bytes))
}
return ElasticsearchExposedCertificate(bytes).apply {
sslContext = container.createSslContextFromCa()
}
}
}
}

data class ElasticSearchExposedConfiguration(
val host: String,
val port: Int,
val password: String,
val certificate: ExposedCertificate
val certificate: Option<ElasticsearchExposedCertificate>
) : ExposedConfiguration

data class ElasticsearchContext(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.trendyol.stove.testing.e2e.elasticsearch

import arrow.integrations.jackson.module.registerArrowModule
import com.fasterxml.jackson.module.kotlin.readValue
import com.trendyol.stove.functional.get
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
import com.trendyol.stove.testing.e2e.system.abstractions.StateWithProcess
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.ints.shouldBeGreaterThan
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe

class ElasticsearchExposedCertificateTest : FunSpec({
test("ser/de") {
val state = """
{
"state": {
"host": "localhost",
"port": 50543,
"password": "password",
"certificate": {
"bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZXakNDQTBLZ0F3SUJBZ0lWQU4wclloSXpaMS90Rmg5NmR3WGI1b1lWWnl4UU1BMEdDU3FHU0liM0RRRUIKQ3dVQU1Ed3hPakE0QmdOVkJBTVRNVVZzWVhOMGFXTnpaV0Z5WTJnZ2MyVmpkWEpwZEhrZ1lYVjBieTFqYjI1bQphV2QxY21GMGFXOXVJRWhVVkZBZ1EwRXdIaGNOTWpNd09ERTFNVGd5TWpJNFdoY05Nall3T0RFME1UZ3lNakk0CldqQThNVG93T0FZRFZRUURFekZGYkdGemRHbGpjMlZoY21Ob0lITmxZM1Z5YVhSNUlHRjFkRzh0WTI5dVptbG4KZFhKaGRHbHZiaUJJVkZSUUlFTkJNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQQppcDVGaWwySUMyRGhYbHkyV3RYTFliTnJUbHNkQklZQ3JvK0N1QU40djJHM3RuMkNQTmVoMnM2V0ovRUNrRitVCndJUVVKWEN0Mm43aEJDWkY4M1BlQ1JabWZyWkE0VXNtdzBYWS9OWWpTcnJRQXVtODYvamFZM0lMVGYzU1Jnei8KaWNFVEJCRVM1eTdmSFZlU0xmTjl1ME9hSC9tTnN5Q3FoMERMRFZrWXR5MHNJZXorb1paNmtxN2UrRE1OeHB5Sgp1cjRvUGJ5ekdmY1dnZDdnMll5T2RxNEd1TmFOck8ySjFVZG5BV3B5TVdnME5TSzd1TGlEZ0w5a25ZZlBnMmhQCisrWVpnVkJNNXJBMXJhY2x3c0U0NWJNVlErKzRyWEhhbDUwdS83VmN6a3M5QTREVDc3ZHVyOC9aM1hONWtpMm0KaWNTemJDTHlLdTZwdUhLQWhCdFMyWnlMMXBYN09RSVA2aWZLaVpaU1ZYUGZnMGk5cjVQL3ZFZTJoVXpTTDRVLwpsSWQvaWJUQWtIcmZGbEErN2FreFNzcFJoalMra1ZTQndyR05KQ3BDbWsraitxSnB5Sis5aTNWb0pkanVvemprClk2bS9EZG9kc21LdUZFYUdZNytBT1RVMjAwN0ZjZWdXUEJWejgzU051WmpwbURCczMzS25oeG5WM0RBb0QzUm4KbkNoV2ZQTGo4TUl1OG9tMll3RUpZMUtLR1hzUzU5TWtyclpuQnNjdzl0S0prMFQyRHlLM2dWckY5UnJpMk1mTwpKY3FCWUhBSHRQTHRQZU5STHJLUmxtYkh4NXJFMkNCWEJWQWJ1bU1EaGRIbE1lTWtwT1p3WnoyQWljWUV1anhlClU0TUl5LzczU1RHakhtcGpVT3dKcjNMdVdqVlBMNDlZeTZZWmNPbENsTThDQXdFQUFhTlRNRkV3SFFZRFZSME8KQkJZRUZNUTlobHVXN3VzdGQwZkZDNU5zSkNyTDhaTStNQjhHQTFVZEl3UVlNQmFBRk1ROWhsdVc3dXN0ZDBmRgpDNU5zSkNyTDhaTStNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBSEdOCjQ1Nm1iYXdKUHNLTVgvQlowanB2LytTbCtMTTB6U2gxeEF1YXlmbDk3WnBlbS80QkhGcU5vTUxGOEVqczhXcHoKUHU1Y3Y5VVFaZXNaWVVsNHE4ODY5TW03QnQ5UHVRcUJBR25VbTU3alhMRkRsdDRvVTFvZmVpalF1YkZ3M0wwMwpGa2NsQ3psZ2JhV21vb2ZKRTdKK2FEMGo5bHNOWllKem9tQlN6QnZGTC9uK0ptS0poQVk4SDNwTkNqdExtbXZjClZPbmluQWFScGxLQndSS1RRYm1ZVE53QXVTcEhvSUk4empqK3pGWm54MzVqSitJY0YwblQ1Q3FQT0tCcllxTmwKN21kTnU0OGs0eUpiY0JtYXNoa3BRdkQra2Q1RFJBWmZXZ2tjZzVZUk1RUnE3RnVpWkhxcmFVdWV2WmZ3dnB2UApqMmV5M0QwMG5aSUVIN3I0alVpVnl0SGNGejVQU29zRmIwZDlmWkRJYmJGanRQblpSTEVxbS8wd3N1V25VSVdRCnlSWTNvclNiMUZIYjdYQUlUdHlnZlZQZnlUV0lnemdtbjFCR3Z2eE5sYjIyVnB4TXcvaEpLWTU0WDRjc2s1RzkKbHZMNUVzT3BvYnZvWVJRNU9taHlJT1ZGSHUwcjRKZWkzcGJ3dTczWmlnLzNFanJLY0lRS0ttYzdhQUFkbGREeQpid0dRWDdvYzRLS1lra2JPNFNNQTRTZzUxQjJFZFEzVGYrSHJlUjFTcHN1TlB1U2p0aGY5MGY2eWYrU1d0NU04CnY2RmpVRy9sR0NGTndJTTd2N1o3SHhMVnIvbVg4MTRKVzBGREdLUmhHRHd3SDUzcTJYSmRaaEl5RlNaeWtuc1UKdmJLeW51Vm43czZrU1pYbnh2NnYyTTNsL09ZMjdpNHdUVnB6bzhXbgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
}
},
"processId": 10496
}
""".trimIndent()
val j = StoveObjectMapper.byConfiguring { this.registerArrowModule() }
val stateWithProcess = j.readValue<StateWithProcess<ElasticSearchExposedConfiguration>>(state)
val serialize = j.writeValueAsString(stateWithProcess)
val stateWithProcess2 = j.readValue<StateWithProcess<ElasticSearchExposedConfiguration>>(serialize)

val cert = stateWithProcess2.state.certificate.get()
cert.bytes.size shouldBeGreaterThan 0
cert.sslContext shouldNotBe null
cert.sslContext.protocol shouldBe "TLSv1.3"
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Reflect<T : Any>(val instance: T) {
propertySelector: T.() -> KProperty<R>
): OnGoingReflect<R> = OnGoingReflect(instance, propertySelector(instance).name)

inline fun <reified R> on(property: String): OnGoingReflect<R> = OnGoingReflect(instance, property)

companion object {
inline operator fun <reified T : Any> invoke(
instance: T,
Expand Down

This file was deleted.

0 comments on commit da45c59

Please sign in to comment.