Merge pull request #28920 from akka/wip-28918-cbor-patriknw
JacksonCborSerializer should use CBOR ofc, #28918
This commit is contained in:
commit
1f448cae2c
4 changed files with 91 additions and 9 deletions
|
|
@ -86,3 +86,32 @@ has been prepared to accept those shorter forms but still emits the old long man
|
|||
|
||||
This means that a rolling update will have to go through at least one of 2.6.2, 2.6.3 or 2.6.4 when upgrading to
|
||||
2.6.5 or higher or else cluster nodes will not be able to communicate during the rolling update.
|
||||
|
||||
### 2.6.5 JacksonCborSerializer
|
||||
|
||||
Issue: [#28918](https://github.com/akka/akka/issues/28918). JacksonCborSerializer was using plain JSON format
|
||||
instead of CBOR.
|
||||
|
||||
If you have `jackson-cbor` in your `serialization-bindings` a rolling upgrade will have to go through 2.6.5 when
|
||||
upgrading to 2.6.5 or higher.
|
||||
|
||||
In Akka 2.6.5 the `jackson-cbor` binding will still serialize to JSON format to support rolling update from 2.6.4.
|
||||
It also adds a new binding to be able to deserialize CBOR format when rolling update from 2.6.5 to 2.6.6.
|
||||
In Akka 2.6.6 the `jackson-cbor` binding will serialize to CBOR and that can be deserialized by 2.6.5. Old
|
||||
data, such as persistent events, can still be deserialized.
|
||||
|
||||
You can start using CBOR format already with Akka 2.6.5 without waiting for the 2.6.6 release. First, perform
|
||||
a rolling update to Akka 2.6.5 using default configuration. Then change the configuration to:
|
||||
|
||||
```
|
||||
akka.actor {
|
||||
serializers {
|
||||
jackson-cbor = "akka.serialization.jackson.JacksonCborSerializer"
|
||||
}
|
||||
serialization-identifiers {
|
||||
jackson-cbor = 33
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Perform a second rolling update with the new configuration.
|
||||
|
|
|
|||
|
|
@ -175,6 +175,13 @@ akka.serialization.jackson {
|
|||
# override the settings in 'akka.serialization.jackson'
|
||||
jackson-cbor {}
|
||||
|
||||
# Issue #28918 for compatibility with data serialized with JacksonCborSerializer in
|
||||
# Akka 2.6.4 or earlier, which was plain JSON format.
|
||||
jackson-cbor-264 = ${akka.serialization.jackson.jackson-cbor}
|
||||
|
||||
# Issue #28918 temporary in Akka 2.6.5 to support rolling update to 2.6.6.
|
||||
jackson-cbor-265 = ${akka.serialization.jackson.jackson-cbor}
|
||||
|
||||
}
|
||||
#//#features
|
||||
|
||||
|
|
@ -195,11 +202,23 @@ akka.serialization.jackson.jackson-json.compression {
|
|||
akka.actor {
|
||||
serializers {
|
||||
jackson-json = "akka.serialization.jackson.JacksonJsonSerializer"
|
||||
jackson-cbor = "akka.serialization.jackson.JacksonCborSerializer"
|
||||
jackson-cbor = "akka.serialization.jackson.JacksonJsonSerializer"
|
||||
|
||||
# Issue #28918 for compatibility with data serialized with JacksonCborSerializer in
|
||||
# Akka 2.6.4 or earlier, which was plain JSON format.
|
||||
jackson-cbor-264 = "akka.serialization.jackson.JacksonJsonSerializer"
|
||||
# Issue #28918 temporary in Akka 2.6.5 to support rolling update to 2.6.6.
|
||||
jackson-cbor-265 = "akka.serialization.jackson.JacksonCborSerializer"
|
||||
}
|
||||
serialization-identifiers {
|
||||
jackson-json = 31
|
||||
jackson-cbor = 32
|
||||
|
||||
# Issue #28918 for compatibility with data serialized with JacksonCborSerializer in
|
||||
# Akka 2.6.4 or earlier, which was plain JSON format.
|
||||
jackson-cbor-264 = 32
|
||||
# Issue #28918 temporary in Akka 2.6.5 to support rolling update to 2.6.6.
|
||||
jackson-cbor-265 = 33
|
||||
}
|
||||
serialization-bindings {
|
||||
# Define bindings for classes or interfaces use Jackson serializer, e.g.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import scala.collection.immutable
|
|||
import scala.compat.java8.OptionConverters._
|
||||
import scala.util.Failure
|
||||
import scala.util.Success
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.ClassicActorSystemProvider
|
||||
import akka.actor.DynamicAccess
|
||||
|
|
@ -70,9 +71,15 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
|||
config: Config,
|
||||
baseJsonFactory: Option[JsonFactory]): JsonFactory = {
|
||||
|
||||
val jsonFactoryBuilder = baseJsonFactory match {
|
||||
case Some(jsonFactory) => new JsonFactoryBuilder(jsonFactory)
|
||||
case None => new JsonFactoryBuilder()
|
||||
val jsonFactory: JsonFactory = baseJsonFactory match {
|
||||
case Some(factory) =>
|
||||
// Issue #28918 not possible to use new JsonFactoryBuilder(jsonFactory) here.
|
||||
// It doesn't preserve the formatParserFeatures and formatGeneratorFeatures in
|
||||
// CBORFactor. Therefore we use JsonFactory and configure the features with mappedFeature
|
||||
// instead of using JsonFactoryBuilder (new in Jackson 2.10.0).
|
||||
factory
|
||||
case None =>
|
||||
new JsonFactoryBuilder().build()
|
||||
}
|
||||
|
||||
val configuredStreamReadFeatures =
|
||||
|
|
@ -82,7 +89,7 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
|||
val streamReadFeatures =
|
||||
objectMapperFactory.overrideConfiguredStreamReadFeatures(bindingName, configuredStreamReadFeatures)
|
||||
streamReadFeatures.foreach {
|
||||
case (feature, value) => jsonFactoryBuilder.configure(feature, value)
|
||||
case (feature, value) => jsonFactory.configure(feature.mappedFeature, value)
|
||||
}
|
||||
|
||||
val configuredStreamWriteFeatures =
|
||||
|
|
@ -92,7 +99,7 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
|||
val streamWriteFeatures =
|
||||
objectMapperFactory.overrideConfiguredStreamWriteFeatures(bindingName, configuredStreamWriteFeatures)
|
||||
streamWriteFeatures.foreach {
|
||||
case (feature, value) => jsonFactoryBuilder.configure(feature, value)
|
||||
case (feature, value) => jsonFactory.configure(feature.mappedFeature, value)
|
||||
}
|
||||
|
||||
val configuredJsonReadFeatures =
|
||||
|
|
@ -102,7 +109,7 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
|||
val jsonReadFeatures =
|
||||
objectMapperFactory.overrideConfiguredJsonReadFeatures(bindingName, configuredJsonReadFeatures)
|
||||
jsonReadFeatures.foreach {
|
||||
case (feature, value) => jsonFactoryBuilder.configure(feature, value)
|
||||
case (feature, value) => jsonFactory.configure(feature.mappedFeature, value)
|
||||
}
|
||||
|
||||
val configuredJsonWriteFeatures =
|
||||
|
|
@ -112,10 +119,10 @@ object JacksonObjectMapperProvider extends ExtensionId[JacksonObjectMapperProvid
|
|||
val jsonWriteFeatures =
|
||||
objectMapperFactory.overrideConfiguredJsonWriteFeatures(bindingName, configuredJsonWriteFeatures)
|
||||
jsonWriteFeatures.foreach {
|
||||
case (feature, value) => jsonFactoryBuilder.configure(feature, value)
|
||||
case (feature, value) => jsonFactory.configure(feature.mappedFeature, value)
|
||||
}
|
||||
|
||||
jsonFactoryBuilder.build()
|
||||
jsonFactory
|
||||
}
|
||||
|
||||
private def configureObjectMapperFeatures(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package akka.serialization.jackson
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
|
|
@ -17,6 +18,7 @@ import java.util.logging.FileHandler
|
|||
import scala.collection.immutable
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.Address
|
||||
|
|
@ -569,6 +571,17 @@ class JacksonJsonSerializerSpec extends JacksonSerializerSpec("jackson-json") {
|
|||
""")(sys => checkSerialization(Elephant("Dumbo", 1), sys))
|
||||
}
|
||||
}
|
||||
|
||||
// issue #28918
|
||||
"cbor compatibility for reading json" in {
|
||||
val msg = SimpleCommand("abc")
|
||||
val jsonSerializer = serializerFor(msg)
|
||||
jsonSerializer.identifier should ===(31)
|
||||
val manifest = jsonSerializer.manifest(msg)
|
||||
val bytes = jsonSerializer.toBinary(msg)
|
||||
val deserialized = serialization().deserialize(bytes, 32, manifest).get
|
||||
deserialized should be(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -626,6 +639,20 @@ abstract class JacksonSerializerSpec(serializerName: String)
|
|||
val manifest = serializer.manifest(obj)
|
||||
val serializerId = serializer.identifier
|
||||
val blob = serializeToBinary(obj)
|
||||
|
||||
// Issue #28918, check that CBOR format is used (not JSON).
|
||||
if (blob.length > 0) {
|
||||
serializer match {
|
||||
case _: JacksonJsonSerializer =>
|
||||
if (!JacksonSerializer.isGZipped(blob))
|
||||
new String(blob.take(1), StandardCharsets.UTF_8) should ===("{")
|
||||
case _: JacksonCborSerializer =>
|
||||
new String(blob.take(1), StandardCharsets.UTF_8) should !==("{")
|
||||
case _ =>
|
||||
throw new IllegalArgumentException(s"Unexpected serializer $serializer")
|
||||
}
|
||||
}
|
||||
|
||||
val deserialized = deserializeFromBinary(blob, serializerId, manifest, sys)
|
||||
deserialized should ===(obj)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue