2023-01-08 17:13:31 +08:00
|
|
|
/*
|
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
|
* license agreements; and to You under the Apache License, version 2.0:
|
|
|
|
|
*
|
|
|
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* This file is part of the Apache Pekko project, derived from Akka.
|
|
|
|
|
*/
|
|
|
|
|
|
2018-10-29 17:19:37 +08:00
|
|
|
/*
|
2022-02-04 12:36:44 +01:00
|
|
|
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
|
2011-12-30 22:00:49 +01:00
|
|
|
*/
|
2018-03-13 23:45:55 +09:00
|
|
|
|
2017-03-16 09:30:00 +01:00
|
|
|
package jdocs.serialization;
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2022-11-12 10:21:24 +01:00
|
|
|
import org.apache.pekko.actor.typed.javadsl.Behaviors;
|
|
|
|
|
import org.apache.pekko.cluster.Cluster;
|
|
|
|
|
import org.apache.pekko.testkit.javadsl.TestKit;
|
2011-12-30 22:00:49 +01:00
|
|
|
import org.junit.Test;
|
2011-12-30 22:13:25 +01:00
|
|
|
import static org.junit.Assert.*;
|
2015-05-28 18:42:22 +02:00
|
|
|
|
2019-01-12 04:00:53 +08:00
|
|
|
// #imports
|
2022-11-12 10:21:24 +01:00
|
|
|
import org.apache.pekko.actor.*;
|
|
|
|
|
import org.apache.pekko.serialization.*;
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2021-05-10 18:00:32 +03:00
|
|
|
import java.nio.charset.Charset;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
|
2019-01-12 04:00:53 +08:00
|
|
|
// #imports
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2013-05-08 09:42:25 +02:00
|
|
|
public class SerializationDocTest {
|
2019-01-12 04:00:53 +08:00
|
|
|
public
|
|
|
|
|
// #my-own-serializer
|
|
|
|
|
static class MyOwnSerializer extends JSerializer {
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2017-03-30 11:31:18 +02:00
|
|
|
// If you need logging here, introduce a constructor that takes an ExtendedActorSystem.
|
2019-01-12 04:00:53 +08:00
|
|
|
// public MyOwnSerializer(ExtendedActorSystem actorSystem)
|
2017-03-30 11:31:18 +02:00
|
|
|
// Get a logger using:
|
2019-01-12 04:00:53 +08:00
|
|
|
// private final LoggingAdapter logger = Logging.getLogger(actorSystem, this);
|
2017-03-30 11:31:18 +02:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// This is whether "fromBinary" requires a "clazz" or not
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public boolean includeManifest() {
|
2012-09-26 10:56:25 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// Pick a unique identifier for your Serializer,
|
|
|
|
|
// you've got a couple of billions to choose from,
|
2023-01-18 08:13:01 +01:00
|
|
|
// 0 - 40 is reserved by Pekko itself
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public int identifier() {
|
2012-09-26 10:56:25 +02:00
|
|
|
return 1234567;
|
|
|
|
|
}
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// "toBinary" serializes the given object to an Array of Bytes
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public byte[] toBinary(Object obj) {
|
2012-09-26 10:56:25 +02:00
|
|
|
// Put the code that serializes the object here
|
2019-01-12 04:00:53 +08:00
|
|
|
// #...
|
2012-09-26 10:56:25 +02:00
|
|
|
return new byte[0];
|
2019-01-12 04:00:53 +08:00
|
|
|
// #...
|
2012-09-26 10:56:25 +02:00
|
|
|
}
|
2011-12-30 22:00:49 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// "fromBinary" deserializes the given array,
|
|
|
|
|
// using the type hint (if any, see "includeManifest" above)
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public Object fromBinaryJava(byte[] bytes, Class<?> clazz) {
|
2012-09-26 10:56:25 +02:00
|
|
|
// Put your code that deserializes here
|
2019-01-12 04:00:53 +08:00
|
|
|
// #...
|
2012-09-26 10:56:25 +02:00
|
|
|
return null;
|
2019-01-12 04:00:53 +08:00
|
|
|
// #...
|
2011-12-30 22:00:49 +01:00
|
|
|
}
|
2012-09-26 10:56:25 +02:00
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #my-own-serializer
|
2012-02-06 21:12:26 +01:00
|
|
|
|
2015-05-28 18:42:22 +02:00
|
|
|
static class Customer {
|
|
|
|
|
public final String name;
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-28 18:42:22 +02:00
|
|
|
Customer(String name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-28 18:42:22 +02:00
|
|
|
static class User {
|
|
|
|
|
public final String name;
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-28 18:42:22 +02:00
|
|
|
User(String name) {
|
|
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
|
|
|
|
public
|
|
|
|
|
// #my-own-serializer2
|
|
|
|
|
static class MyOwnSerializer2 extends SerializerWithStringManifest {
|
2015-05-28 18:42:22 +02:00
|
|
|
|
|
|
|
|
private static final String CUSTOMER_MANIFEST = "customer";
|
|
|
|
|
private static final String USER_MANIFEST = "user";
|
2021-05-10 18:00:32 +03:00
|
|
|
private static final Charset UTF_8 = StandardCharsets.UTF_8;
|
2019-01-12 04:00:53 +08:00
|
|
|
|
2015-05-28 18:42:22 +02:00
|
|
|
// Pick a unique identifier for your Serializer,
|
|
|
|
|
// you've got a couple of billions to choose from,
|
2023-01-18 08:13:01 +01:00
|
|
|
// 0 - 40 is reserved by Pekko itself
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public int identifier() {
|
2015-05-28 18:42:22 +02:00
|
|
|
return 1234567;
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String manifest(Object obj) {
|
|
|
|
|
if (obj instanceof Customer) return CUSTOMER_MANIFEST;
|
|
|
|
|
else if (obj instanceof User) return USER_MANIFEST;
|
|
|
|
|
else throw new IllegalArgumentException("Unknown type: " + obj);
|
2015-05-28 18:42:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "toBinary" serializes the given object to an Array of Bytes
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public byte[] toBinary(Object obj) {
|
2015-05-28 18:42:22 +02:00
|
|
|
// Put the real code that serializes the object here
|
2021-05-10 18:00:32 +03:00
|
|
|
if (obj instanceof Customer) return ((Customer) obj).name.getBytes(UTF_8);
|
|
|
|
|
else if (obj instanceof User) return ((User) obj).name.getBytes(UTF_8);
|
|
|
|
|
else throw new IllegalArgumentException("Unknown type: " + obj);
|
2015-05-28 18:42:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "fromBinary" deserializes the given array,
|
|
|
|
|
// using the type hint
|
2019-01-12 04:00:53 +08:00
|
|
|
@Override
|
|
|
|
|
public Object fromBinary(byte[] bytes, String manifest) {
|
2015-05-28 18:42:22 +02:00
|
|
|
// Put the real code that deserializes here
|
2021-05-10 18:00:32 +03:00
|
|
|
if (manifest.equals(CUSTOMER_MANIFEST)) return new Customer(new String(bytes, UTF_8));
|
|
|
|
|
else if (manifest.equals(USER_MANIFEST)) return new User(new String(bytes, UTF_8));
|
|
|
|
|
else throw new IllegalArgumentException("Unknown manifest: " + manifest);
|
2015-05-28 18:42:22 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-12 04:00:53 +08:00
|
|
|
// #my-own-serializer2
|
2015-05-28 18:42:22 +02:00
|
|
|
|
2019-01-12 04:00:53 +08:00
|
|
|
@Test
|
|
|
|
|
public void serializeActorRefs() {
|
|
|
|
|
final ExtendedActorSystem extendedSystem = (ExtendedActorSystem) ActorSystem.create("whatever");
|
|
|
|
|
final ActorRef theActorRef = extendedSystem.deadLetters(); // Of course this should be you
|
2012-09-26 10:56:25 +02:00
|
|
|
|
2019-01-12 04:00:53 +08:00
|
|
|
// #actorref-serializer
|
2012-09-26 10:56:25 +02:00
|
|
|
// Serialize
|
|
|
|
|
// (beneath toBinary)
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
String serializedRef = Serialization.serializedActorPath(theActorRef);
|
2013-03-25 08:42:48 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// Then just serialize the identifier however you like
|
|
|
|
|
|
|
|
|
|
// Deserialize
|
|
|
|
|
// (beneath fromBinary)
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
final ActorRef deserializedRef = extendedSystem.provider().resolveActorRef(serializedRef);
|
2012-09-26 10:56:25 +02:00
|
|
|
// Then just use the ActorRef
|
2019-01-12 04:00:53 +08:00
|
|
|
// #actorref-serializer
|
2017-03-17 03:02:47 +08:00
|
|
|
TestKit.shutdownActorSystem(extendedSystem);
|
2012-09-26 10:56:25 +02:00
|
|
|
}
|
2012-03-05 11:30:21 +01:00
|
|
|
|
2012-05-15 20:57:39 +02:00
|
|
|
public void demonstrateDefaultAddress() {
|
|
|
|
|
// this is not meant to be run, only to be compiled
|
|
|
|
|
final ActorSystem system = ActorSystem.create();
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
final ActorRef theActorRef = system.deadLetters();
|
2012-05-15 20:57:39 +02:00
|
|
|
// #external-address-default
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
Address selfAddress = Cluster.get(system).selfAddress();
|
|
|
|
|
|
|
|
|
|
String serializedRef = theActorRef.path().toSerializationFormatWithAddress(selfAddress);
|
2012-05-15 20:57:39 +02:00
|
|
|
// #external-address-default
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void demonstrateTheProgrammaticAPI() {
|
2019-01-12 04:00:53 +08:00
|
|
|
// #programmatic
|
2012-05-15 20:57:39 +02:00
|
|
|
ActorSystem system = ActorSystem.create("example");
|
|
|
|
|
|
|
|
|
|
// Get the Serialization Extension
|
|
|
|
|
Serialization serialization = SerializationExtension.get(system);
|
|
|
|
|
|
|
|
|
|
// Have something to serialize
|
|
|
|
|
String original = "woohoo";
|
|
|
|
|
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
// Turn it into bytes, and retrieve the serializerId and manifest, which are needed for
|
|
|
|
|
// deserialization
|
|
|
|
|
byte[] bytes = serialization.serialize(original).get();
|
|
|
|
|
int serializerId = serialization.findSerializerFor(original).identifier();
|
|
|
|
|
String manifest = Serializers.manifestFor(serialization.findSerializerFor(original), original);
|
2012-05-15 20:57:39 +02:00
|
|
|
|
Disable Java serialization by default, #22333 (#27285)
* akka.actor.allow-java-serialization = off
* Moved primitive (Long, Int, String, ByteString) serializers
from akka-remote to akka-actor since they had no dependency
and are useful also in local systems, e.g. persistence.
* e.g. needed for persistence-tck
* less allow-java-serialization=on in tests
* CborSerializable in Jackson/test module for ease of use
* JavaSerializable for Java serialization in tests, already in akka-testkit,
but misconfigured
* Made tests pass
* allow-java-serialization=on in akka-persistence
* allow-java-serialization=on in classic remoting tests
* JavaSerializable and CborSerializable in other remoting tests
* Added serialization for
* Boolean
* java.util.concurrent.TimeoutException, AskTimeoutException
* support for testing serialization with the inmem journal
* utility to verifySerialization, in SerializationTestKit
* remove AccountExampleWithCommandHandlersInState becuase not possible to serialize State when it's not static
* Effect() is factory in EventSourcedBehavior class
* test the account examples
* SharedLeveldbJournal.configToEnableJavaSerializationForTest
* support for exceptions from remote deployed child actors
* fallback to akka.remote.serialization.ThrowableNotSerializableException
if exception is not serializable when wrapped in system messages from
remote deployed child actors and Status.Failure messages
* it's implemented in `WrappedPayloadSupport.payloadBuilder`
* update reference documentation
* serialize-messages=off in most places, separate ticket for
improving or removing that feature
* migration guide, including description of rolling update
* fix 2.13 compiler error
* minor review feedback
2019-07-11 14:04:24 +02:00
|
|
|
// Turn it back into an object
|
|
|
|
|
String back = (String) serialization.deserialize(bytes, serializerId, manifest).get();
|
|
|
|
|
// #programmatic
|
2012-05-15 20:57:39 +02:00
|
|
|
|
|
|
|
|
// Voilá!
|
|
|
|
|
assertEquals(original, back);
|
|
|
|
|
|
2017-03-17 03:02:47 +08:00
|
|
|
TestKit.shutdownActorSystem(system);
|
2012-05-15 20:57:39 +02:00
|
|
|
}
|
2019-09-19 17:53:02 +02:00
|
|
|
|
|
|
|
|
public void demonstrateTheProgrammaticAPITyped() {
|
|
|
|
|
// #programmatic-typed
|
2022-11-12 10:21:24 +01:00
|
|
|
org.apache.pekko.actor.typed.ActorSystem<Void> system =
|
|
|
|
|
org.apache.pekko.actor.typed.ActorSystem.create(Behaviors.empty(), "example");
|
2019-09-19 17:53:02 +02:00
|
|
|
|
|
|
|
|
// Get the Serialization Extension
|
2019-12-17 14:19:42 +01:00
|
|
|
Serialization serialization = SerializationExtension.get(system);
|
2019-09-19 17:53:02 +02:00
|
|
|
// #programmatic-typed
|
|
|
|
|
}
|
2011-12-30 22:00:49 +01:00
|
|
|
}
|