pekko/akka-cluster-tools/src/multi-jvm/scala/akka/cluster/singleton/MultiDcSingletonManagerSpec.scala

129 lines
4.1 KiB
Scala
Raw Normal View History

/*
* Copyright (C) 2017-2019 Lightbend Inc. <https://www.lightbend.com>
*/
package akka.cluster.singleton
import scala.concurrent.duration._
import com.typesafe.config.ConfigFactory
import akka.actor.{ Actor, ActorLogging, Address, PoisonPill, Props }
import akka.cluster.Cluster
import akka.testkit.ImplicitSender
import akka.remote.testkit.{ MultiNodeConfig, MultiNodeSpec, STMultiNodeSpec }
import akka.cluster.ClusterSettings
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
import akka.serialization.jackson.CborSerializable
2017-07-04 17:11:21 +02:00
object MultiDcSingletonManagerSpec extends MultiNodeConfig {
val controller = role("controller")
val first = role("first")
val second = role("second")
val third = role("third")
commonConfig(ConfigFactory.parseString("""
akka.actor.provider = "cluster"
akka.actor.serialize-creators = off
akka.remote.log-remote-lifecycle-events = off"""))
nodeConfig(controller) {
ConfigFactory.parseString("""
akka.cluster.multi-data-center.self-data-center = one
akka.cluster.roles = []""")
}
nodeConfig(first) {
ConfigFactory.parseString("""
akka.cluster.multi-data-center.self-data-center = one
akka.cluster.roles = [ worker ]""")
}
nodeConfig(second, third) {
ConfigFactory.parseString("""
akka.cluster.multi-data-center.self-data-center = two
akka.cluster.roles = [ worker ]""")
}
}
2017-07-04 17:11:21 +02:00
class MultiDcSingletonManagerMultiJvmNode1 extends MultiDcSingletonManagerSpec
class MultiDcSingletonManagerMultiJvmNode2 extends MultiDcSingletonManagerSpec
class MultiDcSingletonManagerMultiJvmNode3 extends MultiDcSingletonManagerSpec
class MultiDcSingletonManagerMultiJvmNode4 extends MultiDcSingletonManagerSpec
2017-07-04 17:11:21 +02:00
class MultiDcSingleton extends Actor with ActorLogging {
import MultiDcSingleton._
val cluster = Cluster(context.system)
override def receive: Receive = {
case Ping =>
sender() ! Pong(cluster.settings.SelfDataCenter, cluster.selfAddress, cluster.selfRoles)
}
}
2017-07-04 17:11:21 +02:00
object MultiDcSingleton {
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
case object Ping extends CborSerializable
case class Pong(fromDc: String, fromAddress: Address, roles: Set[String]) extends CborSerializable
}
2019-03-11 10:38:24 +01:00
abstract class MultiDcSingletonManagerSpec
extends MultiNodeSpec(MultiDcSingletonManagerSpec)
with STMultiNodeSpec
with ImplicitSender {
2017-07-04 17:11:21 +02:00
import MultiDcSingletonManagerSpec._
override def initialParticipants = roles.size
val cluster = Cluster(system)
cluster.join(node(controller).address)
enterBarrier("nodes-joined")
val worker = "worker"
2017-07-04 17:11:21 +02:00
"A SingletonManager in a multi data center cluster" must {
"start a singleton instance for each data center" in {
runOn(first, second, third) {
2019-03-13 10:56:20 +01:00
system.actorOf(
ClusterSingletonManager
.props(Props[MultiDcSingleton](), PoisonPill, ClusterSingletonManagerSettings(system).withRole(worker)),
"singletonManager")
}
2019-03-11 10:38:24 +01:00
val proxy = system.actorOf(
ClusterSingletonProxy.props("/user/singletonManager", ClusterSingletonProxySettings(system).withRole(worker)))
enterBarrier("managers-started")
2017-07-04 17:11:21 +02:00
proxy ! MultiDcSingleton.Ping
val pong = expectMsgType[MultiDcSingleton.Pong](20.seconds)
enterBarrier("pongs-received")
pong.fromDc should equal(Cluster(system).settings.SelfDataCenter)
pong.roles should contain(worker)
runOn(controller, first) {
2017-07-04 17:11:21 +02:00
pong.roles should contain(ClusterSettings.DcRolePrefix + "one")
}
runOn(second, third) {
2017-07-04 17:11:21 +02:00
pong.roles should contain(ClusterSettings.DcRolePrefix + "two")
}
enterBarrier("after-1")
}
2017-07-04 17:11:21 +02:00
"be able to use proxy across different data centers" in {
runOn(third) {
2019-03-11 10:38:24 +01:00
val proxy = system.actorOf(
2019-03-13 10:56:20 +01:00
ClusterSingletonProxy.props(
"/user/singletonManager",
ClusterSingletonProxySettings(system).withRole(worker).withDataCenter("one")))
2017-07-04 17:11:21 +02:00
proxy ! MultiDcSingleton.Ping
val pong = expectMsgType[MultiDcSingleton.Pong](10.seconds)
pong.fromDc should ===("one")
pong.roles should contain(worker)
2017-07-04 17:11:21 +02:00
pong.roles should contain(ClusterSettings.DcRolePrefix + "one")
}
enterBarrier("after-1")
}
}
}