2018-02-11 19:56:52 +01:00
|
|
|
/*
|
2021-01-08 17:55:38 +01:00
|
|
|
* Copyright (C) 2019-2021 Lightbend Inc. <https://www.lightbend.com>
|
2018-02-11 19:56:52 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package doc.akka.serialization.jackson
|
|
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
import java.util.Optional
|
|
|
|
|
|
2019-07-12 09:25:10 +02:00
|
|
|
import akka.actor.ActorSystem
|
2019-07-12 13:31:24 +02:00
|
|
|
import akka.serialization.Serialization
|
2019-07-12 09:25:10 +02:00
|
|
|
import akka.serialization.SerializationExtension
|
2019-07-12 13:31:24 +02:00
|
|
|
import akka.serialization.SerializerWithStringManifest
|
2019-07-12 09:25:10 +02:00
|
|
|
import akka.serialization.Serializers
|
|
|
|
|
import akka.testkit.TestKit
|
2020-09-02 14:19:13 +02:00
|
|
|
import com.fasterxml.jackson.annotation.{ JsonSubTypes, JsonTypeInfo, JsonTypeName }
|
|
|
|
|
import com.fasterxml.jackson.core.JsonParser
|
|
|
|
|
import com.fasterxml.jackson.databind.DeserializationContext
|
|
|
|
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
|
|
|
|
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
|
2019-07-12 09:25:10 +02:00
|
|
|
import com.typesafe.config.ConfigFactory
|
|
|
|
|
import org.scalatest.BeforeAndAfterAll
|
2020-01-11 15:14:21 +03:00
|
|
|
import org.scalatest.matchers.should.Matchers
|
|
|
|
|
import org.scalatest.wordspec.AnyWordSpecLike
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2018-02-11 19:56:52 +01:00
|
|
|
//#marker-interface
|
|
|
|
|
/**
|
|
|
|
|
* Marker interface for messages, events and snapshots that are serialized with Jackson.
|
|
|
|
|
*/
|
|
|
|
|
trait MySerializable
|
|
|
|
|
|
|
|
|
|
final case class Message(name: String, nr: Int) extends MySerializable
|
|
|
|
|
//#marker-interface
|
|
|
|
|
|
|
|
|
|
object SerializationDocSpec {
|
|
|
|
|
val config = """
|
|
|
|
|
#//#serialization-bindings
|
|
|
|
|
akka.actor {
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
"com.myservice.MySerializable" = jackson-json
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#//#serialization-bindings
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
val configMigration = """
|
|
|
|
|
#//#migrations-conf
|
|
|
|
|
akka.serialization.jackson.migrations {
|
|
|
|
|
"com.myservice.event.ItemAdded" = "com.myservice.event.ItemAddedMigration"
|
|
|
|
|
}
|
|
|
|
|
#//#migrations-conf
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
val configMigrationRenamClass = """
|
|
|
|
|
#//#migrations-conf-rename
|
|
|
|
|
akka.serialization.jackson.migrations {
|
2019-06-05 12:31:02 +02:00
|
|
|
"com.myservice.event.OrderAdded" = "com.myservice.event.OrderPlacedMigration"
|
2018-02-11 19:56:52 +01:00
|
|
|
}
|
|
|
|
|
#//#migrations-conf-rename
|
|
|
|
|
"""
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2019-06-02 11:27:03 +02:00
|
|
|
val configSpecific = """
|
|
|
|
|
#//#specific-config
|
|
|
|
|
akka.serialization.jackson.jackson-json {
|
|
|
|
|
serialization-features {
|
|
|
|
|
WRITE_DATES_AS_TIMESTAMPS = off
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
akka.serialization.jackson.jackson-cbor {
|
|
|
|
|
serialization-features {
|
|
|
|
|
WRITE_DATES_AS_TIMESTAMPS = on
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#//#specific-config
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
val configSeveral = """
|
|
|
|
|
#//#several-config
|
|
|
|
|
akka.actor {
|
|
|
|
|
serializers {
|
|
|
|
|
jackson-json-message = "akka.serialization.jackson.JacksonJsonSerializer"
|
|
|
|
|
jackson-json-event = "akka.serialization.jackson.JacksonJsonSerializer"
|
|
|
|
|
}
|
|
|
|
|
serialization-identifiers {
|
|
|
|
|
jackson-json-message = 9001
|
|
|
|
|
jackson-json-event = 9002
|
|
|
|
|
}
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
"com.myservice.MyMessage" = jackson-json-message
|
|
|
|
|
"com.myservice.MyEvent" = jackson-json-event
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
akka.serialization.jackson {
|
|
|
|
|
jackson-json-message {
|
|
|
|
|
serialization-features {
|
|
|
|
|
WRITE_DATES_AS_TIMESTAMPS = on
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
jackson-json-event {
|
|
|
|
|
serialization-features {
|
|
|
|
|
WRITE_DATES_AS_TIMESTAMPS = off
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#//#several-config
|
|
|
|
|
"""
|
|
|
|
|
|
2019-12-05 22:50:01 +11:00
|
|
|
val configManifestless = """
|
|
|
|
|
#//#manifestless
|
|
|
|
|
akka.actor {
|
|
|
|
|
serializers {
|
|
|
|
|
jackson-json-event = "akka.serialization.jackson.JacksonJsonSerializer"
|
|
|
|
|
}
|
|
|
|
|
serialization-identifiers {
|
|
|
|
|
jackson-json-event = 9001
|
|
|
|
|
}
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
"com.myservice.MyEvent" = jackson-json-event
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
akka.serialization.jackson {
|
|
|
|
|
jackson-json-event {
|
|
|
|
|
type-in-manifest = off
|
|
|
|
|
# Since there is exactly one serialization binding declared for this
|
|
|
|
|
# serializer above, this is optional, but if there were none or many,
|
|
|
|
|
# this would be mandatory.
|
|
|
|
|
deserialization-type = "com.myservice.MyEvent"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#//#manifestless
|
|
|
|
|
"""
|
|
|
|
|
|
2020-09-02 14:19:13 +02:00
|
|
|
object Polymorphism {
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2020-09-02 14:19:13 +02:00
|
|
|
//#polymorphism
|
|
|
|
|
final case class Zoo(primaryAttraction: Animal) extends MySerializable
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2020-09-02 14:19:13 +02:00
|
|
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
|
|
|
|
@JsonSubTypes(
|
|
|
|
|
Array(
|
|
|
|
|
new JsonSubTypes.Type(value = classOf[Lion], name = "lion"),
|
|
|
|
|
new JsonSubTypes.Type(value = classOf[Elephant], name = "elephant")))
|
|
|
|
|
sealed trait Animal
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2020-09-02 14:19:13 +02:00
|
|
|
final case class Lion(name: String) extends Animal
|
|
|
|
|
|
|
|
|
|
final case class Elephant(name: String, age: Int) extends Animal
|
|
|
|
|
//#polymorphism
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object PolymorphismMixedClassObject {
|
|
|
|
|
|
|
|
|
|
//#polymorphism-case-object
|
|
|
|
|
final case class Zoo(primaryAttraction: Animal) extends MySerializable
|
|
|
|
|
|
|
|
|
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
|
|
|
|
@JsonSubTypes(
|
|
|
|
|
Array(
|
|
|
|
|
new JsonSubTypes.Type(value = classOf[Lion], name = "lion"),
|
|
|
|
|
new JsonSubTypes.Type(value = classOf[Elephant], name = "elephant"),
|
|
|
|
|
new JsonSubTypes.Type(value = classOf[Unicorn], name = "unicorn")))
|
|
|
|
|
sealed trait Animal
|
|
|
|
|
|
|
|
|
|
final case class Lion(name: String) extends Animal
|
|
|
|
|
final case class Elephant(name: String, age: Int) extends Animal
|
|
|
|
|
|
2021-07-20 19:14:23 +02:00
|
|
|
@JsonDeserialize(`using` = classOf[UnicornDeserializer])
|
2020-09-02 14:19:13 +02:00
|
|
|
sealed trait Unicorn extends Animal
|
|
|
|
|
@JsonTypeName("unicorn")
|
|
|
|
|
case object Unicorn extends Unicorn
|
|
|
|
|
|
|
|
|
|
class UnicornDeserializer extends StdDeserializer[Unicorn](Unicorn.getClass) {
|
|
|
|
|
// whenever we need to deserialize an instance of Unicorn trait, we return the object Unicorn
|
|
|
|
|
override def deserialize(p: JsonParser, ctxt: DeserializationContext): Unicorn = Unicorn
|
|
|
|
|
}
|
|
|
|
|
//#polymorphism-case-object
|
|
|
|
|
}
|
2019-06-07 14:41:01 +02:00
|
|
|
|
2019-05-31 14:59:20 +02:00
|
|
|
val configDateTime = """
|
|
|
|
|
#//#date-time
|
|
|
|
|
akka.serialization.jackson.serialization-features {
|
|
|
|
|
WRITE_DATES_AS_TIMESTAMPS = on
|
2019-10-02 22:58:11 -04:00
|
|
|
WRITE_DURATIONS_AS_TIMESTAMPS = on
|
2019-05-31 14:59:20 +02:00
|
|
|
}
|
|
|
|
|
#//#date-time
|
|
|
|
|
"""
|
2019-06-05 12:31:02 +02:00
|
|
|
|
2020-06-18 15:48:28 +02:00
|
|
|
val configAllowList = """
|
|
|
|
|
#//#allowed-class-prefix
|
|
|
|
|
akka.serialization.jackson.allowed-class-prefix =
|
2019-06-05 12:31:02 +02:00
|
|
|
["com.myservice.event.OrderAdded", "com.myservice.command"]
|
2020-06-18 15:48:28 +02:00
|
|
|
#//#allowed-class-prefix
|
2019-06-05 12:31:02 +02:00
|
|
|
"""
|
|
|
|
|
|
2018-02-11 19:56:52 +01:00
|
|
|
}
|
2019-07-12 09:25:10 +02:00
|
|
|
|
|
|
|
|
class SerializationDocSpec
|
|
|
|
|
extends TestKit(
|
|
|
|
|
ActorSystem(
|
2019-07-12 13:31:24 +02:00
|
|
|
"SerializationDocSpec",
|
2019-07-12 09:25:10 +02:00
|
|
|
ConfigFactory.parseString(s"""
|
2019-07-12 13:31:24 +02:00
|
|
|
akka.serialization.jackson.migrations {
|
|
|
|
|
# migrations for Java classes
|
|
|
|
|
"jdoc.akka.serialization.jackson.v2b.ItemAdded" = "jdoc.akka.serialization.jackson.v2b.ItemAddedMigration"
|
|
|
|
|
"jdoc.akka.serialization.jackson.v2c.ItemAdded" = "jdoc.akka.serialization.jackson.v2c.ItemAddedMigration"
|
|
|
|
|
"jdoc.akka.serialization.jackson.v2a.Customer" = "jdoc.akka.serialization.jackson.v2a.CustomerMigration"
|
|
|
|
|
"jdoc.akka.serialization.jackson.v1.OrderAdded" = "jdoc.akka.serialization.jackson.v2a.OrderPlacedMigration"
|
2019-10-02 22:58:11 -04:00
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
# migrations for Scala classes
|
|
|
|
|
"doc.akka.serialization.jackson.v2b.ItemAdded" = "doc.akka.serialization.jackson.v2b.ItemAddedMigration"
|
|
|
|
|
"doc.akka.serialization.jackson.v2c.ItemAdded" = "doc.akka.serialization.jackson.v2c.ItemAddedMigration"
|
|
|
|
|
"doc.akka.serialization.jackson.v2a.Customer" = "doc.akka.serialization.jackson.v2a.CustomerMigration"
|
|
|
|
|
"doc.akka.serialization.jackson.v1.OrderAdded" = "doc.akka.serialization.jackson.v2a.OrderPlacedMigration"
|
|
|
|
|
}
|
|
|
|
|
akka.actor {
|
|
|
|
|
allow-java-serialization = off
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
"${classOf[jdoc.akka.serialization.jackson.MySerializable].getName}" = jackson-json
|
|
|
|
|
"${classOf[doc.akka.serialization.jackson.MySerializable].getName}" = jackson-json
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
""")))
|
2020-01-11 15:14:21 +03:00
|
|
|
with AnyWordSpecLike
|
2019-07-12 09:25:10 +02:00
|
|
|
with Matchers
|
|
|
|
|
with BeforeAndAfterAll {
|
|
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
val serialization: Serialization = SerializationExtension(system)
|
|
|
|
|
|
2019-07-12 09:25:10 +02:00
|
|
|
override def afterAll(): Unit = {
|
|
|
|
|
shutdown()
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
def verifySerialization(obj: AnyRef): AnyRef = {
|
|
|
|
|
val serializer = serialization.serializerFor(obj.getClass)
|
|
|
|
|
val manifest = Serializers.manifestFor(serializer, obj)
|
|
|
|
|
val serializerId = serializer.identifier
|
|
|
|
|
val blob = serialization.serialize(obj).get
|
|
|
|
|
val deserialized = serialization.deserialize(blob, serializerId, manifest).get
|
|
|
|
|
deserialized
|
2019-07-12 09:25:10 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
private def serializerFor(obj: Any): SerializerWithStringManifest =
|
|
|
|
|
serialization.serializerFor(obj.getClass).asInstanceOf[SerializerWithStringManifest]
|
|
|
|
|
|
2020-09-02 14:19:13 +02:00
|
|
|
"serialize trait + case classes" in {
|
|
|
|
|
import doc.akka.serialization.jackson.SerializationDocSpec.Polymorphism._
|
|
|
|
|
verifySerialization(Zoo(Lion("Simba"))) should ===(Zoo(Lion("Simba")))
|
|
|
|
|
verifySerialization(Zoo(Elephant("Dumbo", 1))) should ===(Zoo(Elephant("Dumbo", 1)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"serialize trait + case classes + case object" in {
|
|
|
|
|
import doc.akka.serialization.jackson.SerializationDocSpec.PolymorphismMixedClassObject._
|
|
|
|
|
verifySerialization(Zoo(Lion("Simba"))) should ===(Zoo(Lion("Simba")))
|
|
|
|
|
verifySerialization(Zoo(Elephant("Dumbo", 1))) should ===(Zoo(Elephant("Dumbo", 1)))
|
|
|
|
|
verifySerialization(Zoo(Unicorn)) should ===(Zoo(Unicorn))
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-12 09:25:10 +02:00
|
|
|
"serialize trait + object ADT" in {
|
|
|
|
|
import CustomAdtSerializer.Compass
|
|
|
|
|
import CustomAdtSerializer.Direction._
|
|
|
|
|
|
2019-07-12 13:31:24 +02:00
|
|
|
verifySerialization(Compass(North)) should ===(Compass(North))
|
|
|
|
|
verifySerialization(Compass(East)) should ===(Compass(East))
|
|
|
|
|
verifySerialization(Compass(South)) should ===(Compass(South))
|
|
|
|
|
verifySerialization(Compass(West)) should ===(Compass(West))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"EventMigration doc sample Java classes" must {
|
|
|
|
|
import jdoc.akka.serialization.jackson.v1.OrderAdded
|
|
|
|
|
import jdoc.akka.serialization.jackson.v2a.Customer
|
|
|
|
|
import jdoc.akka.serialization.jackson.v2a.ItemAdded
|
|
|
|
|
import jdoc.akka.serialization.jackson.v2a.OrderPlaced
|
|
|
|
|
|
|
|
|
|
"test add optional field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
new jdoc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer.fromBinary(blob, classOf[ItemAdded].getName).asInstanceOf[ItemAdded]
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
event2.discount should ===(Optional.empty())
|
|
|
|
|
event2.note should ===("")
|
|
|
|
|
|
|
|
|
|
verifySerialization(new ItemAdded("123", "ab123", 2, Optional.of(0.1), "thanks"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test add mandatory field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
new jdoc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer
|
|
|
|
|
.fromBinary(blob, classOf[jdoc.akka.serialization.jackson.v2b.ItemAdded].getName)
|
|
|
|
|
.asInstanceOf[jdoc.akka.serialization.jackson.v2b.ItemAdded]
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
event2.discount should be(0.0 +- 0.000001)
|
|
|
|
|
|
|
|
|
|
verifySerialization(new jdoc.akka.serialization.jackson.v2b.ItemAdded("123", "ab123", 2, 0.1))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test rename field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
new jdoc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer
|
|
|
|
|
.fromBinary(blob, classOf[jdoc.akka.serialization.jackson.v2c.ItemAdded].getName)
|
|
|
|
|
.asInstanceOf[jdoc.akka.serialization.jackson.v2c.ItemAdded]
|
|
|
|
|
event2.itemId should ===(event1.productId)
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test structural changes" in {
|
|
|
|
|
val cust1 =
|
|
|
|
|
new jdoc.akka.serialization.jackson.v1.Customer("A", "B", "C", "D", "E")
|
|
|
|
|
val serializer = serializerFor(cust1)
|
|
|
|
|
val blob = serializer.toBinary(cust1)
|
|
|
|
|
val cust2 = serializer.fromBinary(blob, classOf[Customer].getName).asInstanceOf[Customer]
|
|
|
|
|
cust2.name should ===(cust1.name)
|
|
|
|
|
cust2.shippingAddress.street should ===(cust1.street)
|
|
|
|
|
cust2.shippingAddress.city should ===(cust1.city)
|
|
|
|
|
cust2.shippingAddress.zipCode should ===(cust1.zipCode)
|
|
|
|
|
cust2.shippingAddress.country should ===(cust1.country)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test rename class" in {
|
|
|
|
|
val order1 = new OrderAdded("1234")
|
|
|
|
|
val serializer = serializerFor(order1)
|
|
|
|
|
val blob = serializer.toBinary(order1)
|
|
|
|
|
val order2 = serializer.fromBinary(blob, classOf[OrderAdded].getName).asInstanceOf[OrderPlaced]
|
|
|
|
|
order2.shoppingCartId should ===(order1.shoppingCartId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"EventMigration doc sample Scala classes" must {
|
|
|
|
|
import doc.akka.serialization.jackson.v1.OrderAdded
|
|
|
|
|
import doc.akka.serialization.jackson.v2a.Customer
|
|
|
|
|
import doc.akka.serialization.jackson.v2a.ItemAdded
|
|
|
|
|
import doc.akka.serialization.jackson.v2a.OrderPlaced
|
|
|
|
|
|
|
|
|
|
"test add optional field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
doc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer.fromBinary(blob, classOf[ItemAdded].getName).asInstanceOf[ItemAdded]
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
event2.discount should ===(None)
|
|
|
|
|
event2.note should ===("")
|
|
|
|
|
|
|
|
|
|
verifySerialization(ItemAdded("123", "ab123", 2, Some(0.1), "thanks"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test add mandatory field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
doc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer
|
|
|
|
|
.fromBinary(blob, classOf[doc.akka.serialization.jackson.v2b.ItemAdded].getName)
|
|
|
|
|
.asInstanceOf[doc.akka.serialization.jackson.v2b.ItemAdded]
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
event2.discount should be(0.0 +- 0.000001)
|
|
|
|
|
|
|
|
|
|
verifySerialization(doc.akka.serialization.jackson.v2b.ItemAdded("123", "ab123", 2, 0.1))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test rename field" in {
|
|
|
|
|
val event1 =
|
|
|
|
|
doc.akka.serialization.jackson.v1.ItemAdded("123", "ab123", 2)
|
|
|
|
|
val serializer = serializerFor(event1)
|
|
|
|
|
val blob = serializer.toBinary(event1)
|
|
|
|
|
val event2 = serializer
|
|
|
|
|
.fromBinary(blob, classOf[doc.akka.serialization.jackson.v2c.ItemAdded].getName)
|
|
|
|
|
.asInstanceOf[doc.akka.serialization.jackson.v2c.ItemAdded]
|
|
|
|
|
event2.itemId should ===(event1.productId)
|
|
|
|
|
event2.quantity should ===(event1.quantity)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test structural changes" in {
|
|
|
|
|
val cust1 =
|
|
|
|
|
doc.akka.serialization.jackson.v1.Customer("A", "B", "C", "D", "E")
|
|
|
|
|
val serializer = serializerFor(cust1)
|
|
|
|
|
val blob = serializer.toBinary(cust1)
|
|
|
|
|
val cust2 = serializer.fromBinary(blob, classOf[Customer].getName).asInstanceOf[Customer]
|
|
|
|
|
cust2.name should ===(cust1.name)
|
|
|
|
|
cust2.shippingAddress.street should ===(cust1.street)
|
|
|
|
|
cust2.shippingAddress.city should ===(cust1.city)
|
|
|
|
|
cust2.shippingAddress.zipCode should ===(cust1.zipCode)
|
|
|
|
|
cust2.shippingAddress.country should ===(cust1.country)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"test rename class" in {
|
|
|
|
|
val order1 = OrderAdded("1234")
|
|
|
|
|
val serializer = serializerFor(order1)
|
|
|
|
|
val blob = serializer.toBinary(order1)
|
|
|
|
|
val order2 = serializer.fromBinary(blob, classOf[OrderAdded].getName).asInstanceOf[OrderPlaced]
|
|
|
|
|
order2.shoppingCartId should ===(order1.shoppingCartId)
|
|
|
|
|
}
|
2019-07-12 09:25:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|