From 6916a76576813ff3763cfc66cee5c6ad3e58579e Mon Sep 17 00:00:00 2001 From: Steven van Beelen Date: Tue, 23 Jul 2024 11:24:53 +0200 Subject: [PATCH 1/8] Add context field for the ReplayTokenSerializer Add context field for the ReplayTokenSerializer. Sadly, the context object is of type Any. Hence, we need to find a way to retrieve a primitive type serializer and potentially configured serializers. #bug/support-reset-context --- .../extensions/kotlin/serialization/AxonSerializers.kt | 9 +++++++-- .../extensions/kotlin/serializer/AxonSerializersTest.kt | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index b7b9c8d6..2e53f385 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -204,23 +204,28 @@ object ReplayTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(ReplayToken::class.java.name) { element("tokenAtReset") element("currentToken") + element("context") } override fun deserialize(decoder: Decoder) = decoder.decodeStructure(descriptor) { var tokenAtReset: TrackingToken? = null var currentToken: TrackingToken? = null + var context: Any? = null while (true) { val index = decodeElementIndex(descriptor) if (index == CompositeDecoder.DECODE_DONE) break when (index) { 0 -> tokenAtReset = decodeSerializableElement(descriptor, index, trackingTokenSerializer) 1 -> currentToken = decodeSerializableElement(descriptor, index, trackingTokenSerializer) + /* replace null for a working serializer that knows how to check the primitives and potentially provided serializers */ + 2 -> context = decodeSerializableElement(descriptor, index, null) } } - ReplayToken( + ReplayToken.createReplayToken( tokenAtReset ?: throw SerializationException("Element 'tokenAtReset' is missing"), currentToken, - ) + context + ) as ReplayToken } override fun serialize(encoder: Encoder, value: ReplayToken) = encoder.encodeStructure(descriptor) { diff --git a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt index 7d36e9cd..2526737e 100644 --- a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt +++ b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt @@ -77,8 +77,10 @@ internal class AxonSerializersTest { @Test fun replayToken() { - val token = ReplayToken.createReplayToken(GlobalSequenceTrackingToken(15), GlobalSequenceTrackingToken(10)) - val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":15},"currentToken":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":10}}""" + val token = ReplayToken.createReplayToken( + GlobalSequenceTrackingToken(15), GlobalSequenceTrackingToken(10), "someContext" + ) + val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":15},"currentToken":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":10},"context":"someContext"}""".trimIndent() assertEquals(json, serializer.serialize(token, String::class.java).data) assertEquals(token, serializer.deserializeTrackingToken(token.javaClass.name, json)) } From 7fa5fba765000be7ae83c88fb6bdcb3ee9da6976 Mon Sep 17 00:00:00 2001 From: Steven van Beelen Date: Tue, 14 Jan 2025 16:43:31 +0100 Subject: [PATCH 2/8] Add todos for the pointer where to work on Add todos for the pointer where to work on #bug/support-reset-context --- .../kotlin/serialization/AxonSerializers.kt | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index 2e53f385..f99dddaf 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2024. Axon Framework + * Copyright (c) 2010-2025. Axon Framework * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,8 +49,14 @@ import org.axonframework.messaging.responsetypes.OptionalResponseType import org.axonframework.messaging.responsetypes.ResponseType import kotlin.reflect.KClass -private val trackingTokenSerializer = PolymorphicSerializer(TrackingToken::class).nullable +/** + * TODO - documentation + */ +val trackingTokenSerializer = PolymorphicSerializer(TrackingToken::class).nullable +/** + * TODO - documentation + */ val AxonSerializersModule = SerializersModule { contextual(ConfigToken::class) { ConfigTokenSerializer } contextual(GapAwareTrackingToken::class) { GapAwareTrackingTokenSerializer } @@ -86,6 +92,9 @@ val AxonSerializersModule = SerializersModule { } } +/** + * TODO - documentation + */ object ConfigTokenSerializer : KSerializer { private val mapSerializer = MapSerializer(String.serializer(), String.serializer()) @@ -112,6 +121,9 @@ object ConfigTokenSerializer : KSerializer { } } +/** + * TODO - documentation + */ object GapAwareTrackingTokenSerializer : KSerializer { private val setSerializer = SetSerializer(Long.serializer()) @@ -143,6 +155,9 @@ object GapAwareTrackingTokenSerializer : KSerializer { } } +/** + * TODO - documentation + */ object MultiSourceTrackingTokenSerializer : KSerializer { private val mapSerializer = MapSerializer(String.serializer(), trackingTokenSerializer) @@ -169,6 +184,9 @@ object MultiSourceTrackingTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(MergedTrackingToken::class.java.name) { @@ -199,6 +217,9 @@ object MergedTrackingTokenSerializer : KSerializer { } } +/** + * TODO - documentation + */ object ReplayTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(ReplayToken::class.java.name) { @@ -210,6 +231,7 @@ object ReplayTokenSerializer : KSerializer { override fun deserialize(decoder: Decoder) = decoder.decodeStructure(descriptor) { var tokenAtReset: TrackingToken? = null var currentToken: TrackingToken? = null + // TODO Fixate context to a String for ease. And, add documentation about this var context: Any? = null while (true) { val index = decodeElementIndex(descriptor) @@ -234,6 +256,9 @@ object ReplayTokenSerializer : KSerializer { } } +/** + * TODO - documentation + */ object GlobalSequenceTrackingTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(GlobalSequenceTrackingToken::class.java.name) { @@ -259,6 +284,9 @@ object GlobalSequenceTrackingTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(SimpleScheduleToken::class.java.name) { @@ -284,6 +312,9 @@ object SimpleScheduleTokenSerializer : KSerializer { } } +/** + * TODO - documentation + */ object QuartzScheduleTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(QuartzScheduleToken::class.java.name) { @@ -339,14 +370,26 @@ abstract class ResponseTypeSerializer>(kClass: KClass, pr } } +/** + * TODO - documentation + */ object InstanceResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(InstanceResponseType::class, { InstanceResponseType(it) }) +/** + * TODO - documentation + */ object OptionalResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(OptionalResponseType::class, { OptionalResponseType(it) }) +/** + * TODO - documentation + */ object MultipleInstancesResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(MultipleInstancesResponseType::class, { MultipleInstancesResponseType(it) }) +/** + * TODO - documentation + */ object ArrayResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(ArrayResponseType::class, { ArrayResponseType(it) }) From 89f2383015b6035645e59b26ee8e538bbec0fce6 Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Mon, 20 Jan 2025 14:04:39 +0100 Subject: [PATCH 3/8] AxonSerializers - add replyTokenContextSerializer for String objects --- .../kotlin/serialization/AxonSerializers.kt | 16 ++++++++++++---- .../kotlin/serializer/AxonSerializersTest.kt | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index f99dddaf..21b35efa 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -53,6 +53,7 @@ import kotlin.reflect.KClass * TODO - documentation */ val trackingTokenSerializer = PolymorphicSerializer(TrackingToken::class).nullable +val replyTokenContextSerializer = String.serializer().nullable /** * TODO - documentation @@ -231,16 +232,14 @@ object ReplayTokenSerializer : KSerializer { override fun deserialize(decoder: Decoder) = decoder.decodeStructure(descriptor) { var tokenAtReset: TrackingToken? = null var currentToken: TrackingToken? = null - // TODO Fixate context to a String for ease. And, add documentation about this - var context: Any? = null + var context: String? = null while (true) { val index = decodeElementIndex(descriptor) if (index == CompositeDecoder.DECODE_DONE) break when (index) { 0 -> tokenAtReset = decodeSerializableElement(descriptor, index, trackingTokenSerializer) 1 -> currentToken = decodeSerializableElement(descriptor, index, trackingTokenSerializer) - /* replace null for a working serializer that knows how to check the primitives and potentially provided serializers */ - 2 -> context = decodeSerializableElement(descriptor, index, null) + 2 -> context = decodeSerializableElement(descriptor, index, replyTokenContextSerializer) } } ReplayToken.createReplayToken( @@ -253,7 +252,16 @@ object ReplayTokenSerializer : KSerializer { override fun serialize(encoder: Encoder, value: ReplayToken) = encoder.encodeStructure(descriptor) { encodeSerializableElement(descriptor, 0, trackingTokenSerializer, value.tokenAtReset) encodeSerializableElement(descriptor, 1, trackingTokenSerializer, value.currentToken) + encodeSerializableElement( + descriptor, + 2, + replyTokenContextSerializer, + stringOrNullFrom(value.context()) + ) } + + private fun stringOrNullFrom(obj: Any?): String? = + obj?.takeIf { it is String }?.let { it as String } } /** diff --git a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt index 2526737e..f1fdccd3 100644 --- a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt +++ b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt @@ -36,6 +36,7 @@ import org.axonframework.messaging.responsetypes.ResponseType import org.axonframework.serialization.Serializer import org.axonframework.serialization.SimpleSerializedObject import org.axonframework.serialization.SimpleSerializedType +import org.axonframework.serialization.json.JacksonSerializer import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test @@ -76,7 +77,7 @@ internal class AxonSerializersTest { } @Test - fun replayToken() { + fun `replay token with String context`() { val token = ReplayToken.createReplayToken( GlobalSequenceTrackingToken(15), GlobalSequenceTrackingToken(10), "someContext" ) @@ -86,13 +87,20 @@ internal class AxonSerializersTest { } @Test - fun `replay token with currentToken with null value`() { - val token = ReplayToken.createReplayToken(GlobalSequenceTrackingToken(5), null) - val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":5},"currentToken":null}""" + fun `replay token with currentToken with null value and null context`() { + val token = ReplayToken.createReplayToken(GlobalSequenceTrackingToken(5), null, null) + val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":5},"currentToken":null,"context":null}""" assertEquals(json, serializer.serialize(token, String::class.java).data) assertEquals(token, serializer.deserializeTrackingToken(token.javaClass.name, json)) } + @Test + fun `replay token deserialize without context field`() { + val token = ReplayToken.createReplayToken(GlobalSequenceTrackingToken(5), null, null) + val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":5},"currentToken":null}""" + assertEquals(token, serializer.deserializeTrackingToken(token.javaClass.name, json)) + } + @Test fun globalSequenceTrackingToken() { val token = GlobalSequenceTrackingToken(5) From 6e477262248221bd753e55cb8ce454540a321097 Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Mon, 20 Jan 2025 15:23:20 +0100 Subject: [PATCH 4/8] add test replay token with complex object as String context --- .../kotlin/serializer/AxonSerializersTest.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt index f1fdccd3..528c5214 100644 --- a/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt +++ b/kotlin/src/test/kotlin/org/axonframework/extensions/kotlin/serializer/AxonSerializersTest.kt @@ -15,6 +15,11 @@ */ package org.axonframework.extensions.kotlin.serializer +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.KotlinModule +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.axonframework.eventhandling.GapAwareTrackingToken import org.axonframework.eventhandling.GlobalSequenceTrackingToken @@ -38,6 +43,7 @@ import org.axonframework.serialization.SimpleSerializedObject import org.axonframework.serialization.SimpleSerializedType import org.axonframework.serialization.json.JacksonSerializer import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertInstanceOf import org.junit.jupiter.api.Test internal class AxonSerializersTest { @@ -101,6 +107,25 @@ internal class AxonSerializersTest { assertEquals(token, serializer.deserializeTrackingToken(token.javaClass.name, json)) } + @Test + fun `replay token with complex object as String context`() { + @Serializable + data class ComplexContext(val value1: String, val value2: Int, val value3: Boolean) + val complexContext = ComplexContext("value1", 2, false) + + val token = ReplayToken.createReplayToken( + GlobalSequenceTrackingToken(15), + GlobalSequenceTrackingToken(10), + Json.encodeToString(complexContext) + ) + val json = """{"tokenAtReset":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":15},"currentToken":{"type":"org.axonframework.eventhandling.GlobalSequenceTrackingToken","globalIndex":10},"context":"{\"value1\":\"value1\",\"value2\":2,\"value3\":false}"}""".trimIndent() + assertEquals(json, serializer.serialize(token, String::class.java).data) + val deserializedToken = serializer.deserializeTrackingToken(token.javaClass.name, json) as ReplayToken + assertEquals(token, deserializedToken) + assertInstanceOf(String::class.java, deserializedToken.context()) + assertEquals(complexContext, Json.decodeFromString(deserializedToken.context() as String)) + } + @Test fun globalSequenceTrackingToken() { val token = GlobalSequenceTrackingToken(5) From 236c7e2f2ca6ce0f1797547a6082a6d026269b33 Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Mon, 20 Jan 2025 15:32:18 +0100 Subject: [PATCH 5/8] AxonSerializers - add KDoc --- .../kotlin/serialization/AxonSerializers.kt | 79 +++++++++++++++---- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index 21b35efa..53604e32 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -50,13 +50,32 @@ import org.axonframework.messaging.responsetypes.ResponseType import kotlin.reflect.KClass /** - * TODO - documentation + * Serializer for Axon's [TrackingToken] class. + * Provides serialization and deserialization support for nullable instances of TrackingToken. + * This serializer uses [replyTokenContextSerializer] to serialize the context field and now only [String] type or null value is supported! + * + * @see TrackingToken */ val trackingTokenSerializer = PolymorphicSerializer(TrackingToken::class).nullable + +/** + * Serializer for the [ReplayToken.context], represented as a nullable String. + * This context is typically used to provide additional information during token replay operations. + * + * This serializer is used by [trackingTokenSerializer] to serialize the context field and now only [String] type or null value is supported! + * Sadly enough, there's no straightforward solution to support [Any]; not without adjusting the context field of the ReplayToken in Axon Framework itself. + * That is, however, a breaking change, and as such, cannot be done till version 5.0.0 of the Axon Framework. + * This also allow more complex objects as the context, although it requires the user to do the de-/serialization to/from String, instead of the Axon Framework itself. + * Look at AxonSerializersTest, case `replay token with complex object as String context` for an example how to handle that using Kotlin Serialization. + * + * @see ReplayToken.context + */ val replyTokenContextSerializer = String.serializer().nullable /** - * TODO - documentation + * Module defining serializers for Axon Framework's core event handling and messaging components. + * This module includes serializers for TrackingTokens, ScheduleTokens, and ResponseTypes, enabling + * seamless integration with Axon-based applications. */ val AxonSerializersModule = SerializersModule { contextual(ConfigToken::class) { ConfigTokenSerializer } @@ -94,7 +113,9 @@ val AxonSerializersModule = SerializersModule { } /** - * TODO - documentation + * Serializer for [ConfigToken]. + * + * @see ConfigToken */ object ConfigTokenSerializer : KSerializer { @@ -123,7 +144,11 @@ object ConfigTokenSerializer : KSerializer { } /** - * TODO - documentation + * Serializer for [GapAwareTrackingToken], which represents tracking tokens with an index and associated gap set. + * + * This implementation supports the serialization and deserialization of tokens that manage tracking gaps. + * + * @see GapAwareTrackingToken */ object GapAwareTrackingTokenSerializer : KSerializer { @@ -157,7 +182,12 @@ object GapAwareTrackingTokenSerializer : KSerializer { } /** - * TODO - documentation + * Serializer for [MultiSourceTrackingToken], which maps source identifiers to corresponding TrackingTokens. + * + * This allows for managing tracking tokens in multi-source scenarios, enabling serialization and deserialization + * of complex token mappings. + * + * @see MultiSourceTrackingToken */ object MultiSourceTrackingTokenSerializer : KSerializer { @@ -186,7 +216,9 @@ object MultiSourceTrackingTokenSerializer : KSerializer { @@ -219,14 +251,17 @@ object MergedTrackingTokenSerializer : KSerializer { } /** - * TODO - documentation + * Serializer for [ReplayToken]. + * The [ReplayToken.context] value can be only a String or null. See [replyTokenContextSerializer] for more information how to handle the context field. + * + * @see ReplayToken */ object ReplayTokenSerializer : KSerializer { override val descriptor = buildClassSerialDescriptor(ReplayToken::class.java.name) { element("tokenAtReset") element("currentToken") - element("context") + element("context") } override fun deserialize(decoder: Decoder) = decoder.decodeStructure(descriptor) { @@ -265,7 +300,9 @@ object ReplayTokenSerializer : KSerializer { } /** - * TODO - documentation + * Serializer for [GlobalSequenceTrackingToken], which includes a global index. + * + * @see GlobalSequenceTrackingToken */ object GlobalSequenceTrackingTokenSerializer : KSerializer { @@ -293,7 +330,9 @@ object GlobalSequenceTrackingTokenSerializer : KSerializer { @@ -321,7 +360,9 @@ object SimpleScheduleTokenSerializer : KSerializer { } /** - * TODO - documentation + * Serializer for [QuartzScheduleToken]. + * + * @see QuartzScheduleToken */ object QuartzScheduleTokenSerializer : KSerializer { @@ -379,25 +420,33 @@ abstract class ResponseTypeSerializer>(kClass: KClass, pr } /** - * TODO - documentation + * Serializer for [InstanceResponseType]. + * + * @see InstanceResponseType */ object InstanceResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(InstanceResponseType::class, { InstanceResponseType(it) }) /** - * TODO - documentation + * Serializer for [OptionalResponseType]. + * + * @see OptionalResponseType */ object OptionalResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(OptionalResponseType::class, { OptionalResponseType(it) }) /** - * TODO - documentation + * Serializer for [MultipleInstancesResponseType]. + * + * @see MultipleInstancesResponseType */ object MultipleInstancesResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(MultipleInstancesResponseType::class, { MultipleInstancesResponseType(it) }) /** - * TODO - documentation + * Serializer for [ArrayResponseType]. + * + * @see ArrayResponseType */ object ArrayResponseTypeSerializer : KSerializer>, ResponseTypeSerializer>(ArrayResponseType::class, { ArrayResponseType(it) }) From c8d02ca2359c270e2d8b57cdbef3f0efe3ce4193 Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Mon, 20 Jan 2025 15:37:59 +0100 Subject: [PATCH 6/8] AxonSerializers - KDoc --- .../kotlin/serialization/AxonSerializers.kt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index 53604e32..0f92aa9c 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -144,9 +144,7 @@ object ConfigTokenSerializer : KSerializer { } /** - * Serializer for [GapAwareTrackingToken], which represents tracking tokens with an index and associated gap set. - * - * This implementation supports the serialization and deserialization of tokens that manage tracking gaps. + * Serializer for [GapAwareTrackingToken]. * * @see GapAwareTrackingToken */ @@ -182,10 +180,7 @@ object GapAwareTrackingTokenSerializer : KSerializer { } /** - * Serializer for [MultiSourceTrackingToken], which maps source identifiers to corresponding TrackingTokens. - * - * This allows for managing tracking tokens in multi-source scenarios, enabling serialization and deserialization - * of complex token mappings. + * Serializer for [MultiSourceTrackingToken]. * * @see MultiSourceTrackingToken */ @@ -216,7 +211,7 @@ object MultiSourceTrackingTokenSerializer : KSerializer { /** * Serializer for [ReplayToken]. - * The [ReplayToken.context] value can be only a String or null. See [replyTokenContextSerializer] for more information how to handle the context field. + * The [ReplayToken.context] value can be only a String or null. + * See [replyTokenContextSerializer] for more information how to handle the context field. * * @see ReplayToken */ @@ -300,7 +296,7 @@ object ReplayTokenSerializer : KSerializer { } /** - * Serializer for [GlobalSequenceTrackingToken], which includes a global index. + * Serializer for [GlobalSequenceTrackingToken]. * * @see GlobalSequenceTrackingToken */ From 86cea715a943437335def56e4244f75ad9801f11 Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Mon, 3 Feb 2025 13:17:44 +0100 Subject: [PATCH 7/8] fix typo `replayTokenContextSerializer` --- .../extensions/kotlin/serialization/AxonSerializers.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index 0f92aa9c..8f266049 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -52,7 +52,7 @@ import kotlin.reflect.KClass /** * Serializer for Axon's [TrackingToken] class. * Provides serialization and deserialization support for nullable instances of TrackingToken. - * This serializer uses [replyTokenContextSerializer] to serialize the context field and now only [String] type or null value is supported! + * This serializer uses [replayTokenContextSerializer] to serialize the context field and now only [String] type or null value is supported! * * @see TrackingToken */ @@ -70,7 +70,7 @@ val trackingTokenSerializer = PolymorphicSerializer(TrackingToken::class).nullab * * @see ReplayToken.context */ -val replyTokenContextSerializer = String.serializer().nullable +val replayTokenContextSerializer = String.serializer().nullable /** * Module defining serializers for Axon Framework's core event handling and messaging components. @@ -248,7 +248,7 @@ object MergedTrackingTokenSerializer : KSerializer { /** * Serializer for [ReplayToken]. * The [ReplayToken.context] value can be only a String or null. - * See [replyTokenContextSerializer] for more information how to handle the context field. + * See [replayTokenContextSerializer] for more information how to handle the context field. * * @see ReplayToken */ @@ -270,7 +270,7 @@ object ReplayTokenSerializer : KSerializer { when (index) { 0 -> tokenAtReset = decodeSerializableElement(descriptor, index, trackingTokenSerializer) 1 -> currentToken = decodeSerializableElement(descriptor, index, trackingTokenSerializer) - 2 -> context = decodeSerializableElement(descriptor, index, replyTokenContextSerializer) + 2 -> context = decodeSerializableElement(descriptor, index, replayTokenContextSerializer) } } ReplayToken.createReplayToken( @@ -286,7 +286,7 @@ object ReplayTokenSerializer : KSerializer { encodeSerializableElement( descriptor, 2, - replyTokenContextSerializer, + replayTokenContextSerializer, stringOrNullFrom(value.context()) ) } From 74917248ff013d1010cc5bc4a6ba26d204b8d78e Mon Sep 17 00:00:00 2001 From: Mateusz Nowak Date: Tue, 11 Feb 2025 12:45:57 +0100 Subject: [PATCH 8/8] fix docs --- .../extensions/kotlin/serialization/AxonSerializers.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt index 8f266049..2721a6c8 100644 --- a/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt +++ b/kotlin/src/main/kotlin/org/axonframework/extensions/kotlin/serialization/AxonSerializers.kt @@ -52,7 +52,6 @@ import kotlin.reflect.KClass /** * Serializer for Axon's [TrackingToken] class. * Provides serialization and deserialization support for nullable instances of TrackingToken. - * This serializer uses [replayTokenContextSerializer] to serialize the context field and now only [String] type or null value is supported! * * @see TrackingToken */ @@ -248,9 +247,10 @@ object MergedTrackingTokenSerializer : KSerializer { /** * Serializer for [ReplayToken]. * The [ReplayToken.context] value can be only a String or null. - * See [replayTokenContextSerializer] for more information how to handle the context field. + * This serializer uses [replayTokenContextSerializer] to serialize the context field and now only [String] type or null value is supported! * * @see ReplayToken + * @see [replayTokenContextSerializer] */ object ReplayTokenSerializer : KSerializer {