vert-x3 / vertx-examples

Vert.x examples
Apache License 2.0
3.55k stars 2.09k forks source link

Event bus codec doesn't work for a list of objet #452

Open ZouhairBear opened 1 year ago

ZouhairBear commented 1 year ago

Context

I have used this exemple CustomMessageCodec to make a codec for a simple object. It works for a simple object so I wanted to use for a list of objects. This didn't work.

Exemple of used Codec class

import fr.convergence.proddoc.common.model.surcharge.SurchargeDocument
import fr.convergence.proddoc.common.util.json
import io.vertx.core.buffer.Buffer
import io.vertx.core.eventbus.MessageCodec
import io.vertx.mutiny.core.Vertx
import kotlinx.serialization.builtins.ListSerializer
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class SurchargeDocumentListCodecRegistering {
    @Inject
    constructor(vertx: Vertx) {
        vertx.eventBus().registerCodec(SurchargeDocumentListCodec())
    }
}

class SurchargeDocumentListCodec : MessageCodec<List<SurchargeDocument>, List<SurchargeDocument>> {

    override fun encodeToWire(buffer: Buffer, list: List<SurchargeDocument>) {

        val encodedList = json.encodeToString(ListSerializer(SurchargeDocument.serializer()), list)
        val length = encodedList.toByteArray().size
        buffer.appendInt(length)
        buffer.appendString(encodedList)
    }

    override fun decodeFromWire(position: Int, buffer: Buffer): List<SurchargeDocument> {
        var _pos = position
        val length = buffer.getInt(_pos)
        val jsonContent = buffer.getString(4.let { _pos += it; _pos }, length.let { _pos += it; _pos })
        return json.decodeFromString(ListSerializer(SurchargeDocument.serializer()), jsonContent)
    }

    override fun transform(list: List<SurchargeDocument>): List<SurchargeDocument> {
        return list.toList() // Transform as needed
    }

    override fun name(): String {
        return this.javaClass.simpleName
    }

    override fun systemCodecID(): Byte {
        return -1
    }
}

Extra

tsegismont commented 1 year ago

This will not work because Vert.x has no way to know if the list object was templated.

If your objects are all annotated with Jackson databind annotations, you could use a default codec selector: https://vertx.io/blog/whats-new-in-vert-x-4-3/#dynamic-codec-lookup