Skip to content

Commit

Permalink
ObjectMapper is the first class citizen for ser/de #34 (#35)
Browse files Browse the repository at this point in the history
* ObjectMapper is the first class citizen for ser/de #34

* add byConfiguring

* apply ktlint

* add elasticsearch to the coverage
  • Loading branch information
osoykan authored Feb 14, 2023
1 parent 1ae3989 commit cca5d3b
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ root = true

[*]
insert_final_newline = true
disabled_rules = no-wildcard-imports, filename, import-ordering
ktlint_disabled_rules = no-wildcard-imports, filename, import-ordering

[{*.kt,*.kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
kotlin("jvm").version(libs.versions.kotlin)
alias(libs.plugins.dokka)
alias(libs.plugins.ktlint)
alias(libs.plugins.palantirGitVersioning)
alias(libs.plugins.gitVersioning)
id("stove-publishing") apply false
id("coverage")
java
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/coverage.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {
dependencies {
jacocoAggregation(project(":lib:stove-testing-e2e"))
jacocoAggregation(project(":lib:stove-testing-e2e-couchbase"))
jacocoAggregation(project(":lib:stove-testing-e2e-elasticsearch"))
jacocoAggregation(project(":lib:stove-testing-e2e-http"))
jacocoAggregation(project(":lib:stove-testing-e2e-kafka"))
jacocoAggregation(project(":lib:stove-testing-e2e-wiremock"))
Expand Down
3 changes: 1 addition & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,5 @@ ktlint = { id = "org.jlleitschuh.gradle.ktlint", version = "11.2.0" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
knit = { id = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "knit" }
kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
gitVersioning = { id = "me.qoomon.git-versioning", version = "6.4.0" }
palantirGitVersioning = { id = "com.palantir.git-version", version = "1.0.0" }
gitVersioning = { id = "com.palantir.git-version", version = "1.0.0" }

Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ package com.trendyol.stove.testing.e2e.couchbase
import arrow.core.getOrElse
import com.couchbase.client.core.msg.kv.DurabilityLevel.PERSIST_TO_MAJORITY
import com.couchbase.client.java.*
import com.couchbase.client.java.codec.JsonSerializer
import com.couchbase.client.java.codec.JacksonJsonSerializer
import com.couchbase.client.java.env.ClusterEnvironment
import com.couchbase.client.java.json.JsonObject
import com.couchbase.client.java.json.JsonValueModule
import com.couchbase.client.java.kv.InsertOptions
import com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS
import com.fasterxml.jackson.databind.ObjectMapper
import com.trendyol.stove.functional.Try
import com.trendyol.stove.functional.recover
import com.trendyol.stove.testing.e2e.containers.DEFAULT_REGISTRY
import com.trendyol.stove.testing.e2e.containers.withProvidedRegistry
import com.trendyol.stove.testing.e2e.couchbase.ClusterExtensions.executeQueryAs
import com.trendyol.stove.testing.e2e.database.DocumentDatabaseSystem
import com.trendyol.stove.testing.e2e.serialization.StoveJacksonJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.abstractions.ConfiguresExposedConfiguration
import com.trendyol.stove.testing.e2e.system.abstractions.ExposedConfiguration
Expand All @@ -31,7 +32,6 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.testcontainers.couchbase.BucketDefinition
import org.testcontainers.couchbase.CouchbaseContainer
import kotlin.jvm.internal.Reflection
import kotlin.reflect.KClass

data class CouchbaseExposedConfiguration(
Expand All @@ -45,7 +45,7 @@ data class CouchbaseSystemOptions(
val defaultBucket: String,
val registry: String = DEFAULT_REGISTRY,
override val configureExposedConfiguration: (CouchbaseExposedConfiguration) -> List<String> = { _ -> listOf() },
val jsonSerializer: StoveJsonSerializer = StoveJacksonJsonSerializer(),
val objectMapper: ObjectMapper = StoveObjectMapper.byConfiguring { registerModule(JsonValueModule()) },
) : SystemOptions, ConfiguresExposedConfiguration<CouchbaseExposedConfiguration>

fun TestSystem.withCouchbase(
Expand Down Expand Up @@ -82,7 +82,7 @@ class CouchbaseSystem internal constructor(
private lateinit var collection: ReactiveCollection
private lateinit var exposedConfiguration: CouchbaseExposedConfiguration

private val objectMapper: StoveJsonSerializer = context.options.jsonSerializer
private val objectMapper: ObjectMapper = context.options.objectMapper
private val logger: Logger = LoggerFactory.getLogger(javaClass)

override suspend fun run() {
Expand Down Expand Up @@ -119,8 +119,8 @@ class CouchbaseSystem internal constructor(
val result = cluster.executeQueryAs<Any>(query) { queryOptions -> queryOptions.scanConsistency(REQUEST_PLUS) }

val objects = result
.map { objectMapper.serialize(it) }
.map { objectMapper.deserialize(it, clazz) }
.map { objectMapper.writeValueAsString(it) }
.map { objectMapper.readValue(it, clazz.java) }

assertion(objects)
return this
Expand Down Expand Up @@ -157,7 +157,7 @@ class CouchbaseSystem internal constructor(
.collection(collection)
.insert(
id,
JsonObject.fromJson(objectMapper.serialize(instance)),
JsonObject.fromJson(objectMapper.writeValueAsString(instance)),
InsertOptions.insertOptions().durability(PERSIST_TO_MAJORITY)
)
.awaitSingle()
Expand All @@ -184,7 +184,7 @@ class CouchbaseSystem internal constructor(

private fun createCluster(exposedConfiguration: CouchbaseExposedConfiguration): ReactiveCluster =
ClusterEnvironment.builder()
.jsonSerializer(jsonSerializer())
.jsonSerializer(JacksonJsonSerializer.create(objectMapper))
.build()
.let {
Cluster.connect(
Expand All @@ -194,13 +194,4 @@ class CouchbaseSystem internal constructor(
.environment(it)
).reactive()
}

private fun jsonSerializer(): JsonSerializer = object : JsonSerializer {
override fun serialize(input: Any): ByteArray = objectMapper.serializeAsBytes(input)

override fun <T : Any> deserialize(
target: Class<T>,
input: ByteArray,
): T = objectMapper.deserialize(input, Reflection.getOrCreateKotlinClass(target)) as T
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import co.elastic.clients.elasticsearch.core.DeleteRequest
import co.elastic.clients.elasticsearch.core.SearchRequest
import co.elastic.clients.json.jackson.JacksonJsonpMapper
import co.elastic.clients.transport.rest_client.RestClientTransport
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.trendyol.stove.testing.e2e.containers.withProvidedRegistry
import com.trendyol.stove.testing.e2e.database.DocumentDatabaseSystem
import com.trendyol.stove.testing.e2e.serialization.StoveJacksonJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.abstractions.*
import org.apache.http.HttpHost
Expand All @@ -34,7 +34,7 @@ data class ElasticsearchSystemOptions(
val defaultIndex: DefaultIndex,
val containerOptions: ContainerOptions = ContainerOptions(),
override val configureExposedConfiguration: (ElasticSearchExposedConfiguration) -> List<String> = { _ -> listOf() },
val jsonSerializer: StoveJsonSerializer = StoveJacksonJsonSerializer(),
val objectMapper: ObjectMapper = StoveObjectMapper.Default,
) : SystemOptions, ConfiguresExposedConfiguration<ElasticSearchExposedConfiguration> {

internal val migrationCollection: MigrationCollection = MigrationCollection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ package com.trendyol.stove.testing.e2e.http

import arrow.core.Option
import arrow.core.getOrElse
import com.trendyol.stove.testing.e2e.serialization.StoveJacksonJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.deserialize
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.abstractions.SystemNotRegisteredException
import com.trendyol.stove.testing.e2e.system.abstractions.SystemOptions
Expand All @@ -22,19 +22,19 @@ import java.time.Duration
import kotlinx.coroutines.future.await
import kotlin.reflect.KClass

data class HttpClientSystemOptions(val jsonSerializer: StoveJsonSerializer = StoveJacksonJsonSerializer()) : SystemOptions
data class HttpClientSystemOptions(val objectMapper: ObjectMapper = StoveObjectMapper.Default) : SystemOptions

@Deprecated(
"This method is deprecated, going to be removed",
replaceWith = ReplaceWith("withHttpClient()", "com.trendyol.stove.testing.e2e.http.TestSystem")
)
fun TestSystem.withDefaultHttp(jsonSerializer: StoveJsonSerializer = StoveJacksonJsonSerializer()): TestSystem {
fun TestSystem.withDefaultHttp(jsonSerializer: ObjectMapper = StoveObjectMapper.Default): TestSystem {
this.getOrRegister(DefaultHttpSystem(this, jsonSerializer))
return this
}

fun TestSystem.withHttpClient(options: HttpClientSystemOptions = HttpClientSystemOptions()): TestSystem {
this.getOrRegister(DefaultHttpSystem(this, options.jsonSerializer))
this.getOrRegister(DefaultHttpSystem(this, options.objectMapper))
return this
}

Expand All @@ -54,7 +54,7 @@ fun TestSystem.http(): DefaultHttpSystem =

class DefaultHttpSystem(
override val testSystem: TestSystem,
private val json: StoveJsonSerializer,
private val objectMapper: ObjectMapper,
) : HttpSystem {
private val httpClient: HttpClient = httpClient()

Expand All @@ -72,7 +72,7 @@ class DefaultHttpSystem(
token.map { request.setHeader(Headers.Authentication, Headers.bearer(it)) }
body.fold(
ifEmpty = { request.POST(BodyPublishers.noBody()) },
ifSome = { request.POST(BodyPublishers.ofString(json.serialize(it))) }
ifSome = { request.POST(BodyPublishers.ofString(objectMapper.writeValueAsString(it))) }
)
}.let { expect(deserialize(it, clazz)); this }

Expand All @@ -85,7 +85,7 @@ class DefaultHttpSystem(
token.map { request.setHeader(Headers.Authentication, Headers.bearer(it)) }
body.fold(
ifEmpty = { request.POST(BodyPublishers.noBody()) },
ifSome = { request.POST(BodyPublishers.ofString(json.serialize(it))) }
ifSome = { request.POST(BodyPublishers.ofString(objectMapper.writeValueAsString(it))) }
)
}.let { expect(StoveHttpResponse(it.statusCode(), it.headers().map())); this }

Expand All @@ -107,7 +107,7 @@ class DefaultHttpSystem(
): DefaultHttpSystem = httpClient.send(uri) { request ->
token.map { request.setHeader(Headers.Authentication, Headers.bearer(it)) }
request.GET()
}.let { expect(json.deserialize(it.body())); this }
}.let { expect(objectMapper.readValue(it.body())); this }

override suspend fun getResponse(
uri: String,
Expand Down Expand Up @@ -145,7 +145,7 @@ class DefaultHttpSystem(
clazz: KClass<TExpected>,
): TExpected = when {
clazz.java.isAssignableFrom(String::class.java) -> String(it.body()) as TExpected
else -> json.deserialize(it.body(), clazz)
else -> objectMapper.readValue(it.body(), clazz.java)
}

override fun close() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ package com.trendyol.stove.testing.e2e.kafka

import arrow.core.Option
import arrow.core.getOrElse
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.trendyol.stove.testing.e2e.containers.DEFAULT_REGISTRY
import com.trendyol.stove.testing.e2e.containers.withProvidedRegistry
import com.trendyol.stove.testing.e2e.kafka.intercepting.InterceptionOptions
import com.trendyol.stove.testing.e2e.kafka.intercepting.TestSystemKafkaInterceptor
import com.trendyol.stove.testing.e2e.messaging.MessagingSystem
import com.trendyol.stove.testing.e2e.serialization.StoveJacksonJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import com.trendyol.stove.testing.e2e.serialization.deserialize
import com.trendyol.stove.testing.e2e.serialization.StoveObjectMapper
import com.trendyol.stove.testing.e2e.system.TestSystem
import com.trendyol.stove.testing.e2e.system.abstractions.*
import io.github.nomisRev.kafka.Admin
Expand Down Expand Up @@ -40,7 +40,7 @@ data class KafkaSystemOptions(
val registry: String = DEFAULT_REGISTRY,
val ports: List<Int> = listOf(9092, 9093),
val errorTopicSuffixes: List<String> = listOf("error", "errorTopic", "retry", "retryTopic"),
val jsonSerializer: StoveJsonSerializer = StoveJacksonJsonSerializer(),
val objectMapper: ObjectMapper = StoveObjectMapper.Default,
override val configureExposedConfiguration: (KafkaExposedConfiguration) -> List<String> = { _ -> listOf() },
) : SystemOptions, ConfiguresExposedConfiguration<KafkaExposedConfiguration>

Expand Down Expand Up @@ -115,7 +115,7 @@ class KafkaSystem(
override suspend fun afterRun() {
interceptor = TestSystemKafkaInterceptor(
adminClient,
StoveJacksonJsonSerializer(),
context.options.objectMapper,
InterceptionOptions(errorTopicSuffixes = context.options.errorTopicSuffixes)
)
subscribeToAllConsumer = SubscribeToAll(
Expand Down Expand Up @@ -178,19 +178,19 @@ class KafkaSystem(
}

class StoveKafkaValueDeserializer<T : Any> : Deserializer<T> {
private val jsonSerializer = StoveJacksonJsonSerializer()
private val objectMapper = StoveObjectMapper.Default

@Suppress("UNCHECKED_CAST")
override fun deserialize(
topic: String,
data: ByteArray,
): T = jsonSerializer.deserialize<Any>(data) as T
): T = objectMapper.readValue<Any>(data) as T
}

class StoveKafkaValueSerializer<T : Any> : Serializer<T> {
private val jsonSerializer = StoveJacksonJsonSerializer()
private val objectMapper = StoveObjectMapper.Default
override fun serialize(
topic: String,
data: T,
): ByteArray = jsonSerializer.serializeAsBytes(data)
): ByteArray = objectMapper.writeValueAsBytes(data)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import arrow.core.Option
import arrow.core.align
import arrow.core.handleErrorWith
import arrow.core.toOption
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.trendyol.stove.testing.e2e.kafka.KafkaSystem
import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import java.util.UUID
import java.util.concurrent.ConcurrentMap
import kotlinx.coroutines.TimeoutCancellationException
Expand All @@ -27,7 +27,7 @@ data class KafkaAssertion<T : Any>(

internal interface CommonOps : RecordsAssertions {
val exceptions: ConcurrentMap<UUID, Failure>
val serde: StoveJsonSerializer
val serde: ObjectMapper
val adminClient: Admin

suspend fun <T> (() -> Collection<T>).waitUntilConditionMet(
Expand Down Expand Up @@ -60,7 +60,7 @@ internal interface CommonOps : RecordsAssertions {
clazz: KClass<T>,
): Result<T> = runCatching {
when (json) {
is String -> serde.deserialize(json, clazz)
is String -> serde.readValue(json, clazz.java)
else -> jacksonObjectMapper().convertValue(json, clazz.java)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.trendyol.stove.testing.e2e.kafka.intercepting

import com.trendyol.stove.testing.e2e.serialization.StoveJsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
Expand All @@ -12,7 +12,7 @@ import org.slf4j.LoggerFactory

class TestSystemKafkaInterceptor(
override val adminClient: Admin,
override val serde: StoveJsonSerializer,
override val serde: ObjectMapper,
private val options: InterceptionOptions,
) : ConsumingOps, CommonOps, AutoCloseable {

Expand Down
Loading

0 comments on commit cca5d3b

Please sign in to comment.