Как я могу принимать разные типы полезных данных и преобразовывать их в соответствующую схему AVRO в Kotlin? - PullRequest
1 голос
/ 28 мая 2020

У меня есть Kotlin (Micronaut) ServerWebSocket , который получает различные типы полезных данных. Все эти полезные данные имеют свойство topic, которое соответствует топологии Kafka c, которая ожидает определенный тип c схемы AVRO. С входящей строкой topi c я могу получить правильную схему AVRO и класс, который был создан для нее.

В том виде, как я реализовал это сейчас, он может получать все, но я не могу Кажется, что он переводит его в правильный класс, поскольку я получаю сообщение об ошибке: Cannot cast java.util.LinkedHashMap to ExampleOne

data class WSMessage <T> (val topic: String, val payload: T)

@ServerWebSocket("/ws")
class WebSocket(...) {

    @OnMessage
    fun <T> onMessage(session: WebSocketSession, message: WSMessage<T>) {
        val payload = validate(message)
    }
    
    private fun <T> validate(msg: WSMessage<T>): SpecificRecord? {
        val schema = topics.find { it.topic == msg.topic }?.schema ?: throw NullPointerException("Topic '${msg.topic}' is unknown")
        val schemaClass = Class.forName(schema)

        // ERROR: Cannot cast java.util.LinkedHashMap to PersonalMessage
        val test = schemaClass.cast(msg.payload)

        return test
    }

}

Поскольку входящий тип T в основном такой же, как Any, я не могу получить его работать так. Он работает отлично, однако, если я укажу, что ожидаю параметр message: WSMessage<ExampleOne>, он автоматически превратит сообщение в WSMessage<ExampleOne> для меня без каких-либо проблем.

Однако это полезно только в том случае, если я буду только получать полезные данные типа ExampleOne, тогда как я буду получать полезные данные с разными типами, поэтому он также должен поддерживать ExampleTwo и любые другие указанные мной классы. Самым оптимальным решением было бы принять любую SpecificRecord , который реализует каждый класс схемы AVRO, однако изменение его на <T: SpecificRecord> не помогает.

Есть ли другие type Я могу заменить входящий тип T на, чтобы в дальнейшем преобразовать его в правильный тип? Или я могу определить различные возможные типы, чтобы он знал, что это должен быть один из них? , но это вовсе не надежно, поскольку я обнаружил, что даже изменение порядка различных функций может нарушить его. И это могло бы стать большим беспорядком.

...