parent
9aa0e593b0
commit
9a4674f42f
2 changed files with 77 additions and 3 deletions
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Lightbend Inc. <https://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.actor.typed
|
||||
|
||||
import akka.actor.ActorPath
|
||||
import akka.actor.ActorRefProvider
|
||||
import akka.actor.ActorSystemImpl
|
||||
import akka.actor.MinimalActorRef
|
||||
import akka.actor.RootActorPath
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import org.scalatest.Matchers
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.concurrent.ScalaFutures
|
||||
|
||||
class ActorRefResolverSpec extends WordSpec with ScalaFutures with Matchers {
|
||||
"ActorRefResolver" should {
|
||||
"not allow serialization of ref originating from other system" in {
|
||||
val system1 = ActorSystem(Behaviors.empty[String], "sys1")
|
||||
val system2 = ActorSystem(Behaviors.empty[String], "sys2")
|
||||
try {
|
||||
val ref1 = system1.systemActorOf(Behaviors.empty, "ref1")
|
||||
val serialized = ActorRefResolver(system1).toSerializationFormat(ref1)
|
||||
serialized should startWith("akka://sys1/")
|
||||
|
||||
intercept[IllegalArgumentException] {
|
||||
// wrong system
|
||||
ActorRefResolver(system2).toSerializationFormat(ref1)
|
||||
}
|
||||
|
||||
// we can't detect that for MinimalActorRef
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
|
||||
val minRef1: akka.actor.ActorRef = new MinimalActorRef {
|
||||
override def provider: ActorRefProvider = system1.toClassic.asInstanceOf[ActorSystemImpl].provider
|
||||
override def path: ActorPath = RootActorPath(provider.getDefaultAddress) / "minRef1"
|
||||
}
|
||||
|
||||
val minRef1Serialized = ActorRefResolver(system2).toSerializationFormat(minRef1)
|
||||
minRef1Serialized should startWith("akka://sys2/")
|
||||
|
||||
} finally {
|
||||
system1.terminate()
|
||||
system2.terminate()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package akka.actor.typed
|
||||
|
||||
import akka.actor.ActorRefWithCell
|
||||
import akka.actor.ExtendedActorSystem
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.annotation.InternalApi
|
||||
|
|
@ -35,7 +36,7 @@ abstract class ActorRefResolver extends Extension {
|
|||
def toSerializationFormat[T](ref: ActorRef[T]): String
|
||||
|
||||
/**
|
||||
* Deserialize an `ActorRef` in the [[#toSerializationFormat]].
|
||||
* Deserialize an `ActorRef` in the [[ActorRefResolver#toSerializationFormat]].
|
||||
*/
|
||||
def resolveActorRef[T](serializedActorRef: String): ActorRef[T]
|
||||
|
||||
|
|
@ -49,8 +50,30 @@ abstract class ActorRefResolver extends Extension {
|
|||
|
||||
private val classicSystem = system.toClassic.asInstanceOf[ExtendedActorSystem]
|
||||
|
||||
override def toSerializationFormat[T](ref: ActorRef[T]): String =
|
||||
ref.path.toSerializationFormatWithAddress(classicSystem.provider.getDefaultAddress)
|
||||
override def toSerializationFormat[T](ref: ActorRef[T]): String = {
|
||||
|
||||
def toSerializationFormatWithAddress =
|
||||
ref.path.toSerializationFormatWithAddress(classicSystem.provider.getDefaultAddress)
|
||||
|
||||
ref.toClassic match {
|
||||
case a: ActorRefWithCell =>
|
||||
val originSystem = a.underlying.system.asInstanceOf[ExtendedActorSystem]
|
||||
if (originSystem eq classicSystem)
|
||||
toSerializationFormatWithAddress
|
||||
else
|
||||
throw new IllegalArgumentException(
|
||||
s"ActorRefResolver for ActorSystem [${classicSystem.provider.getDefaultAddress}] shouldn't be used for " +
|
||||
"serialization of ActorRef that originates from another ActorSystem " +
|
||||
s"[${originSystem.provider.getDefaultAddress}]. Use the ActorRefResolver for that system instead.")
|
||||
|
||||
case _ =>
|
||||
// no origin system information for RemoteActorRef or MinimalActorRef, so just use the
|
||||
// one for this extension. That is correct for RemoteActorRef, but MinimalActorRef
|
||||
// could be wrong. However, since we don't allow usage of "wrong" ActorSystem for
|
||||
// ordinary ActorRef the users will learn not to make that mistake.
|
||||
toSerializationFormatWithAddress
|
||||
}
|
||||
}
|
||||
|
||||
override def resolveActorRef[T](serializedActorRef: String): ActorRef[T] =
|
||||
classicSystem.provider.resolveActorRef(serializedActorRef)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue