1- package streams.serialization
1+ package streams.utils
22
33import com.fasterxml.jackson.core.JsonGenerator
44import com.fasterxml.jackson.core.JsonParseException
@@ -12,7 +12,6 @@ import org.neo4j.driver.internal.value.PointValue
1212import org.neo4j.graphdb.spatial.Point
1313import org.neo4j.values.storable.CoordinateReferenceSystem
1414import streams.events.*
15- import streams.utils.StreamsUtils
1615import java.io.IOException
1716import java.time.temporal.TemporalAccessor
1817import kotlin.reflect.full.isSubclassOf
@@ -35,8 +34,7 @@ fun Point.toStreamsPoint(): StreamsPoint {
3534
3635fun PointValue.toStreamsPoint (): StreamsPoint {
3736 val point = this .asPoint()
38- val crsType = point.srid()
39- return when (crsType) {
37+ return when (val crsType = point.srid()) {
4038 CoordinateReferenceSystem .Cartesian .code -> StreamsPointCartesian (CoordinateReferenceSystem .Cartesian .name, point.x(), point.y())
4139 CoordinateReferenceSystem .Cartesian_3D .code -> StreamsPointCartesian (CoordinateReferenceSystem .Cartesian_3D .name, point.x(), point.y(), point.z())
4240 CoordinateReferenceSystem .WGS84 .code -> StreamsPointWgs (CoordinateReferenceSystem .WGS84 .name, point.x(), point.y())
@@ -82,20 +80,22 @@ class TemporalAccessorSerializer : JsonSerializer<TemporalAccessor>() {
8280object JSONUtils {
8381
8482 private val OBJECT_MAPPER : ObjectMapper = jacksonObjectMapper()
83+ private val STRICT_OBJECT_MAPPER : ObjectMapper = jacksonObjectMapper()
8584
8685 init {
8786 val module = SimpleModule (" Neo4jKafkaSerializer" )
88- StreamsUtils .ignoreExceptions({ module.addSerializer(Point ::class .java, PointSerializer ()) }, NoClassDefFoundError ::class .java, UnsupportedClassVersionError :: class .java ) // in case is loaded from
89- StreamsUtils .ignoreExceptions({ module.addSerializer(PointValue ::class .java, PointValueSerializer ()) }, NoClassDefFoundError ::class .java, UnsupportedClassVersionError :: class .java ) // in case is loaded from
87+ StreamsUtils .ignoreExceptions({ module.addSerializer(Point ::class .java, PointSerializer ()) }, NoClassDefFoundError ::class .java) // in case is loaded from
88+ StreamsUtils .ignoreExceptions({ module.addSerializer(PointValue ::class .java, PointValueSerializer ()) }, NoClassDefFoundError ::class .java) // in case is loaded from
9089 module.addSerializer(TemporalAccessor ::class .java, TemporalAccessorSerializer ())
9190 OBJECT_MAPPER .registerModule(module)
9291 OBJECT_MAPPER .disable(SerializationFeature .FAIL_ON_EMPTY_BEANS )
9392 OBJECT_MAPPER .disable(DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES )
93+ STRICT_OBJECT_MAPPER .registerModule(module)
9494 }
9595
96- fun getObjectMapper (): ObjectMapper {
97- return OBJECT_MAPPER
98- }
96+ fun getObjectMapper (): ObjectMapper = OBJECT_MAPPER
97+
98+ fun getStrictObjectMapper (): ObjectMapper = STRICT_OBJECT_MAPPER
9999
100100 fun asMap (any : Any ): Map <String , Any ?> {
101101 return OBJECT_MAPPER .convertValue(any, Map ::class .java)
@@ -114,60 +114,52 @@ object JSONUtils {
114114 return getObjectMapper().readValue(value, T ::class .java)
115115 }
116116
117- inline fun <reified T > readValue (value : Any , stringWhenFailure : Boolean = false): T {
118- val strValue = when (value) {
119- is String -> value
120- is ByteArray -> String (value)
121- else -> getObjectMapper().writeValueAsString(value)
122- }
117+ inline fun <reified T > readValue (value : Any ,
118+ stringWhenFailure : Boolean = false,
119+ objectMapper : ObjectMapper = getObjectMapper()): T {
123120 return try {
124- getObjectMapper().readValue(strValue)
125- } catch (e: JsonParseException ) {
121+ when (value) {
122+ is String -> objectMapper.readValue(value)
123+ is ByteArray -> objectMapper.readValue(value)
124+ else -> objectMapper.convertValue(value)
125+ }
126+ } catch (e: JsonParseException ) {
126127 if (stringWhenFailure && String ::class .isSubclassOf(T ::class )) {
128+ val strValue = when (value) {
129+ is ByteArray -> String (value)
130+ null -> " "
131+ else -> value.toString()
132+ }
127133 strValue.trimStart().let {
128- if (it.get( 0 ) == ' {' || it.get( 0 ) == ' [' ) throw e
134+ if (it[ 0 ] == ' {' || it[ 0 ] == ' [' ) throw e
129135 else it as T
130136 }
131137 }
132138 else throw e
133139 }
134140 }
135141
136- inline fun <reified T > convertValue (value : Any ): T {
137- return getObjectMapper() .convertValue(value)
142+ inline fun <reified T > convertValue (value : Any , objectMapper : ObjectMapper = getObjectMapper() ): T {
143+ return objectMapper .convertValue(value)
138144 }
139145
140- @Suppress(" UNCHECKED_CAST" )
141146 fun asStreamsTransactionEvent (obj : Any ): StreamsTransactionEvent {
142- if (obj is StreamsTransactionEvent ) {
143- return obj
144- }
145- val value = when (obj) {
146- is Map <* , * > -> obj as Map <String , Map <String , Any >>
147- is String -> readValue(obj)
148- is ByteArray -> readValue(obj)
149- else -> convertValue(obj)
150- }
151- val meta = convertValue<Meta >(value.getValue(" meta" ))
152-
153- val schema = convertValue<Schema >(value.getValue(" schema" ))
154-
155- val payloadMap = value.getValue(" payload" )
156- val type = payloadMap.getValue(" type" ).toString()
157- val id = payloadMap.getValue(" id" ).toString()
158-
159- val payload = if (type == " node" ) {
160- val before = if (payloadMap[" before" ] != null ) convertValue<NodeChange >(payloadMap[" before" ]!! ) else null
161- val after = if (payloadMap[" after" ] != null ) convertValue<NodeChange >(payloadMap[" after" ]!! ) else null
162- NodePayload (id, before, after)
163- } else {
164- val label= payloadMap.getValue(" label" ).toString()
165- val start = convertValue<RelationshipNodeChange >(payloadMap.getValue(" start" ))
166- val end = convertValue<RelationshipNodeChange >(payloadMap.getValue(" end" ))
167- val before = if (payloadMap[" before" ] != null ) convertValue<RelationshipChange >(payloadMap[" before" ]!! ) else null
168- val after = if (payloadMap[" after" ] != null ) convertValue<RelationshipChange >(payloadMap[" after" ]!! ) else null
169- RelationshipPayload (id, start, end, before, after, label)
147+ return try {
148+ val evt = when (obj) {
149+ is String , is ByteArray -> readValue<StreamsTransactionNodeEvent >(value = obj,
150+ objectMapper = STRICT_OBJECT_MAPPER )
151+ else -> convertValue<StreamsTransactionNodeEvent >(value = obj,
152+ objectMapper = STRICT_OBJECT_MAPPER )
153+ }
154+ evt.toStreamsTransactionEvent()
155+ } catch (e: Exception ) {
156+ val evt = when (obj) {
157+ is String , is ByteArray -> readValue<StreamsTransactionRelationshipEvent >(value = obj,
158+ objectMapper = STRICT_OBJECT_MAPPER )
159+ else -> convertValue<StreamsTransactionRelationshipEvent >(value = obj,
160+ objectMapper = STRICT_OBJECT_MAPPER )
161+ }
162+ evt.toStreamsTransactionEvent()
170163 }
171- return StreamsTransactionEvent (meta, payload, schema)
172164 }
173165}
0 commit comments