diff --git a/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java b/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java index f8600f3e1b..9678cbc76d 100644 --- a/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java +++ b/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java @@ -26,7 +26,7 @@ public class JavaAPI { @Test public void mustBeAbleToCreateActorRefFromClass() { - ActorRef ref = system.actorOf(JavaAPITestActor.class); + ActorRef ref = system.actorOf(new Props(JavaAPITestActor.class)); assertNotNull(ref); } @@ -42,7 +42,7 @@ public class JavaAPI { @Test public void mustAcceptSingleArgTell() { - ActorRef ref = system.actorOf(JavaAPITestActor.class); + ActorRef ref = system.actorOf(new Props(JavaAPITestActor.class)); ref.tell("hallo"); ref.tell("hallo", ref); } diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala index 2537b996ad..aa7d76d3dc 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorFireForgetRequestReplySpec.scala @@ -63,16 +63,16 @@ class ActorFireForgetRequestReplySpec extends AkkaSpec with BeforeAndAfterEach w "An Actor" must { "reply to bang message using reply" in { - val replyActor = system.actorOf[ReplyActor] - val senderActor = system.actorOf(new SenderActor(replyActor)) + val replyActor = system.actorOf(Props[ReplyActor]) + val senderActor = system.actorOf(Props(new SenderActor(replyActor))) senderActor ! "Init" state.finished.await state.s must be("Reply") } "reply to bang message using implicit sender" in { - val replyActor = system.actorOf[ReplyActor] - val senderActor = system.actorOf(new SenderActor(replyActor)) + val replyActor = system.actorOf(Props[ReplyActor]) + val senderActor = system.actorOf(Props(new SenderActor(replyActor))) senderActor ! "InitImplicit" state.finished.await state.s must be("ReplyImplicit") diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala index b3b8ece741..f1cca42011 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala @@ -145,82 +145,82 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { filterException[akka.actor.ActorInitializationException] { intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new Actor { + actorOf(Props(new Actor { val nested = promiseIntercept(new Actor { def receive = { case _ ⇒ } })(result) def receive = { case _ ⇒ } - })) + }))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(promiseIntercept(new FailingOuterActor(actorOf(new InnerActor)))(result))) + actorOf(Props(promiseIntercept(new FailingOuterActor(actorOf(Props(new InnerActor))))(result)))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new OuterActor(actorOf(promiseIntercept(new FailingInnerActor)(result))))) + actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(promiseIntercept(new FailingInheritingOuterActor(actorOf(new InnerActor)))(result))) + actorOf(Props(promiseIntercept(new FailingInheritingOuterActor(actorOf(Props(new InnerActor))))(result)))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new FailingOuterActor(actorOf(promiseIntercept(new FailingInheritingInnerActor)(result))))) + actorOf(Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new FailingInheritingOuterActor(actorOf(promiseIntercept(new FailingInheritingInnerActor)(result))))) + actorOf(Props(new FailingInheritingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new FailingInheritingOuterActor(actorOf(promiseIntercept(new FailingInnerActor)(result))))) + actorOf(Props(new FailingInheritingOuterActor(actorOf(Props(promiseIntercept(new FailingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new OuterActor(actorOf(new InnerActor { + actorOf(Props(new OuterActor(actorOf(Props(new InnerActor { val a = promiseIntercept(new InnerActor)(result) - })))) + })))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new FailingOuterActor(actorOf(promiseIntercept(new FailingInheritingInnerActor)(result))))) + actorOf(Props(new FailingOuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new OuterActor(actorOf(promiseIntercept(new FailingInheritingInnerActor)(result))))) + actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept(new FailingInheritingInnerActor)(result))))))) } contextStackMustBeEmpty intercept[akka.actor.ActorInitializationException] { wrap(result ⇒ - actorOf(new OuterActor(actorOf(promiseIntercept({ new InnerActor; new InnerActor })(result))))) + actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept({ new InnerActor; new InnerActor })(result))))))) } contextStackMustBeEmpty @@ -229,7 +229,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { filterException[java.lang.IllegalStateException] { (intercept[java.lang.IllegalStateException] { wrap(result ⇒ - actorOf(new OuterActor(actorOf(promiseIntercept({ throw new IllegalStateException("Ur state be b0rked"); new InnerActor })(result))))) + actorOf(Props(new OuterActor(actorOf(Props(promiseIntercept({ throw new IllegalStateException("Ur state be b0rked"); new InnerActor })(result))))))) }).getMessage must be === "Ur state be b0rked" contextStackMustBeEmpty @@ -237,7 +237,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { } "be serializable using Java Serialization on local node" in { - val a = system.actorOf[InnerActor] + val a = system.actorOf(Props[InnerActor]) import java.io._ @@ -260,7 +260,7 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { } "throw an exception on deserialize if no system in scope" in { - val a = system.actorOf[InnerActor] + val a = system.actorOf(Props[InnerActor]) import java.io._ @@ -301,10 +301,10 @@ class ActorRefSpec extends AkkaSpec with DefaultTimeout { } "support nested actorOfs" in { - val a = system.actorOf(new Actor { - val nested = system.actorOf(new Actor { def receive = { case _ ⇒ } }) + val a = system.actorOf(Props(new Actor { + val nested = system.actorOf(Props(new Actor { def receive = { case _ ⇒ } })) def receive = { case _ ⇒ sender ! nested } - }) + })) val nested = (a ? "any").as[ActorRef].get a must not be null diff --git a/akka-actor-tests/src/test/scala/akka/actor/Bench.scala b/akka-actor-tests/src/test/scala/akka/actor/Bench.scala index 52a18e0f3b..4ef5a94b12 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/Bench.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/Bench.scala @@ -76,7 +76,7 @@ object Chameneos { var numFaded = 0 override def preStart() = { - for (i ← 0 until numChameneos) context.actorOf(new Chameneo(self, colours(i % 3), i)) + for (i ← 0 until numChameneos) context.actorOf(Props(new Chameneo(self, colours(i % 3), i))) } def receive = { @@ -107,7 +107,7 @@ object Chameneos { def run { // System.setProperty("akka.config", "akka.conf") Chameneos.start = System.currentTimeMillis - val system = ActorSystem().actorOf(new Mall(1000000, 4)) + val system = ActorSystem().actorOf(Props(new Mall(1000000, 4))) Thread.sleep(10000) println("Elapsed: " + (end - start)) system.stop() diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala index 0f09c3e1d2..e4a30e10e0 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMActorSpec.scala @@ -112,14 +112,14 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im import latches._ // lock that locked after being open for 1 sec - val lock = system.actorOf(new Lock("33221", 1 second, latches)) + val lock = system.actorOf(Props(new Lock("33221", 1 second, latches))) - val transitionTester = system.actorOf(new Actor { + val transitionTester = system.actorOf(Props(new Actor { def receive = { case Transition(_, _, _) ⇒ transitionCallBackLatch.open case CurrentState(_, Locked) ⇒ initialStateLatch.open } - }) + })) lock ! SubscribeTransitionCallBack(transitionTester) initialStateLatch.await @@ -143,13 +143,13 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im val answerLatch = TestLatch() object Hello object Bye - val tester = system.actorOf(new Actor { + val tester = system.actorOf(Props(new Actor { protected def receive = { case Hello ⇒ lock ! "hello" case "world" ⇒ answerLatch.open case Bye ⇒ lock ! "bye" } - }) + })) tester ! Hello answerLatch.await @@ -185,7 +185,7 @@ class FSMActorSpec extends AkkaSpec(Map("akka.actor.debug.fsm" -> true)) with Im case x ⇒ testActor ! x } } - val ref = system.actorOf(fsm) + val ref = system.actorOf(Props(fsm)) started.await ref.stop() expectMsg(1 second, fsm.StopEvent(Shutdown, 1, null)) diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala index 85bd70248f..2d7534c755 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMTimingSpec.scala @@ -14,7 +14,7 @@ class FSMTimingSpec extends AkkaSpec with ImplicitSender { import FSMTimingSpec._ import FSM._ - val fsm = system.actorOf(new StateMachine(testActor)) + val fsm = system.actorOf(Props(new StateMachine(testActor))) fsm ! SubscribeTransitionCallBack(testActor) expectMsg(1 second, CurrentState(fsm, Initial)) diff --git a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala index 7c67d8e1e1..1b1f90e5b3 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/FSMTransitionSpec.scala @@ -56,7 +56,7 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { "A FSM transition notifier" must { "notify listeners" in { - val fsm = system.actorOf(new MyFSM(testActor)) + val fsm = system.actorOf(Props(new MyFSM(testActor))) within(1 second) { fsm ! SubscribeTransitionCallBack(testActor) expectMsg(CurrentState(fsm, 0)) @@ -68,8 +68,8 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { } "not fail when listener goes away" in { - val forward = system.actorOf(new Forwarder(testActor)) - val fsm = system.actorOf(new MyFSM(testActor)) + val forward = system.actorOf(Props(new Forwarder(testActor))) + val fsm = system.actorOf(Props(new MyFSM(testActor))) val sup = system.actorOf(Props(new Actor { context.watch(fsm) def receive = { case _ ⇒ } @@ -88,7 +88,7 @@ class FSMTransitionSpec extends AkkaSpec with ImplicitSender { "A FSM" must { "make previous and next state data available in onTransition" in { - val fsm = system.actorOf(new OtherFSM(testActor)) + val fsm = system.actorOf(Props(new OtherFSM(testActor))) within(300 millis) { fsm ! "tick" expectMsg((0, 1)) diff --git a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala index 86af471d13..aa2cd4c9ff 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ForwardActorSpec.scala @@ -13,14 +13,14 @@ object ForwardActorSpec { val ExpectedMessage = "FOO" def createForwardingChain(system: ActorSystem): ActorRef = { - val replier = system.actorOf(new Actor { + val replier = system.actorOf(Props(new Actor { def receive = { case x ⇒ sender ! x } - }) + })) - def mkforwarder(forwardTo: ActorRef) = system.actorOf( + def mkforwarder(forwardTo: ActorRef) = system.actorOf(Props( new Actor { def receive = { case x ⇒ forwardTo forward x } - }) + })) mkforwarder(mkforwarder(mkforwarder(replier))) } @@ -35,7 +35,7 @@ class ForwardActorSpec extends AkkaSpec { "forward actor reference when invoking forward on bang" in { val latch = new TestLatch(1) - val replyTo = system.actorOf(new Actor { def receive = { case ExpectedMessage ⇒ latch.countDown() } }) + val replyTo = system.actorOf(Props(new Actor { def receive = { case ExpectedMessage ⇒ latch.countDown() } })) val chain = createForwardingChain(system) diff --git a/akka-actor-tests/src/test/scala/akka/actor/HotSwapSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/HotSwapSpec.scala index d63104f2ca..e3027a4c00 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/HotSwapSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/HotSwapSpec.scala @@ -12,12 +12,12 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender { "An Actor" must { "be able to hotswap its behavior with become(..)" in { - val a = system.actorOf(new Actor { + val a = system.actorOf(Props(new Actor { def receive = { case "init" ⇒ sender ! "init" case "swap" ⇒ context.become({ case x: String ⇒ context.sender ! x }) } - }) + })) a ! "init" expectMsg("init") @@ -27,7 +27,7 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender { } "be able to revert hotswap its behavior with unbecome" in { - val a = system.actorOf(new Actor { + val a = system.actorOf(Props(new Actor { def receive = { case "init" ⇒ sender ! "init" case "swap" ⇒ @@ -38,7 +38,7 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender { context.unbecome() }) } - }) + })) a ! "init" expectMsg("init") @@ -54,7 +54,7 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender { "revert to initial state on restart" in { - val a = system.actorOf(new Actor { + val a = system.actorOf(Props(new Actor { def receive = { case "state" ⇒ sender ! "0" case "swap" ⇒ @@ -65,7 +65,7 @@ class HotSwapSpec extends AkkaSpec with ImplicitSender { }) sender ! "swapped" } - }) + })) a ! "state" expectMsg("0") a ! "swap" diff --git a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala index 8e15f5fbbe..f2127d92bc 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala @@ -46,7 +46,7 @@ object IOActorSpec { class SimpleEchoClient(host: String, port: Int, ioManager: ActorRef) extends Actor with IO { lazy val socket: SocketHandle = connect(ioManager, host, port)(reader) - lazy val reader: ActorRef = context.actorOf { + lazy val reader: ActorRef = context.actorOf(Props({ new Actor with IO { def receiveIO = { case length: Int ⇒ @@ -54,7 +54,7 @@ object IOActorSpec { sender ! bytes } } - } + })) def receiveIO = { case bytes: ByteString ⇒ @@ -186,10 +186,10 @@ class IOActorSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { "an IO Actor" must { "run echo server" in { val started = TestLatch(1) - val ioManager = system.actorOf(new IOManager(2)) // teeny tiny buffer - val server = system.actorOf(new SimpleEchoServer("localhost", 8064, ioManager, started)) + val ioManager = system.actorOf(Props(new IOManager(2))) // teeny tiny buffer + val server = system.actorOf(Props(new SimpleEchoServer("localhost", 8064, ioManager, started))) started.await - val client = system.actorOf(new SimpleEchoClient("localhost", 8064, ioManager)) + val client = system.actorOf(Props(new SimpleEchoClient("localhost", 8064, ioManager))) val f1 = client ? ByteString("Hello World!1") val f2 = client ? ByteString("Hello World!2") val f3 = client ? ByteString("Hello World!3") @@ -203,10 +203,10 @@ class IOActorSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { "run echo server under high load" in { val started = TestLatch(1) - val ioManager = system.actorOf(new IOManager()) - val server = system.actorOf(new SimpleEchoServer("localhost", 8065, ioManager, started)) + val ioManager = system.actorOf(Props(new IOManager())) + val server = system.actorOf(Props(new SimpleEchoServer("localhost", 8065, ioManager, started))) started.await - val client = system.actorOf(new SimpleEchoClient("localhost", 8065, ioManager)) + val client = system.actorOf(Props(new SimpleEchoClient("localhost", 8065, ioManager))) val list = List.range(0, 1000) val f = Future.traverse(list)(i ⇒ client ? ByteString(i.toString)) assert(f.get.size === 1000) @@ -217,10 +217,10 @@ class IOActorSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { "run echo server under high load with small buffer" in { val started = TestLatch(1) - val ioManager = system.actorOf(new IOManager(2)) - val server = system.actorOf(new SimpleEchoServer("localhost", 8066, ioManager, started)) + val ioManager = system.actorOf(Props(new IOManager(2))) + val server = system.actorOf(Props(new SimpleEchoServer("localhost", 8066, ioManager, started))) started.await - val client = system.actorOf(new SimpleEchoClient("localhost", 8066, ioManager)) + val client = system.actorOf(Props(new SimpleEchoClient("localhost", 8066, ioManager))) val list = List.range(0, 1000) val f = Future.traverse(list)(i ⇒ client ? ByteString(i.toString)) assert(f.get.size === 1000) @@ -231,11 +231,11 @@ class IOActorSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout { "run key-value store" in { val started = TestLatch(1) - val ioManager = system.actorOf(new IOManager(2)) // teeny tiny buffer - val server = system.actorOf(new KVStore("localhost", 8067, ioManager, started)) + val ioManager = system.actorOf(Props(new IOManager(2))) // teeny tiny buffer + val server = system.actorOf(Props(new KVStore("localhost", 8067, ioManager, started))) started.await - val client1 = system.actorOf(new KVClient("localhost", 8067, ioManager)) - val client2 = system.actorOf(new KVClient("localhost", 8067, ioManager)) + val client1 = system.actorOf(Props(new KVClient("localhost", 8067, ioManager))) + val client2 = system.actorOf(Props(new KVClient("localhost", 8067, ioManager))) val f1 = client1 ? (('set, "hello", ByteString("World"))) val f2 = client1 ? (('set, "test", ByteString("No one will read me"))) val f3 = client1 ? (('get, "hello")) diff --git a/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala index 991332871c..ad92865124 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/LocalActorRefProviderSpec.scala @@ -42,12 +42,12 @@ class LocalActorRefProviderSpec extends AkkaSpec { } "only create one instance of an actor from within the same message invocation" in { - val supervisor = system.actorOf(new Actor { + val supervisor = system.actorOf(Props(new Actor { def receive = { case "" ⇒ val a, b = context.actorOf(Props.empty, "duplicate") } - }) + })) EventFilter[InvalidActorNameException](occurrences = 1) intercept { supervisor ! "" } diff --git a/akka-actor-tests/src/test/scala/akka/actor/ReceiveTimeoutSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ReceiveTimeoutSpec.scala index bccf4da5c7..02b5aab8c1 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ReceiveTimeoutSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ReceiveTimeoutSpec.scala @@ -17,13 +17,13 @@ class ReceiveTimeoutSpec extends AkkaSpec { "get timeout" in { val timeoutLatch = TestLatch() - val timeoutActor = system.actorOf(new Actor { - context.receiveTimeout = Some(500 milliseconds) + val timeoutActor = system.actorOf(Props(new Actor { + context.setReceiveTimeout(500 milliseconds) protected def receive = { case ReceiveTimeout ⇒ timeoutLatch.open } - }) + })) timeoutLatch.await timeoutActor.stop() @@ -33,14 +33,14 @@ class ReceiveTimeoutSpec extends AkkaSpec { val timeoutLatch = TestLatch() case object Tick - val timeoutActor = system.actorOf(new Actor { - context.receiveTimeout = Some(500 milliseconds) + val timeoutActor = system.actorOf(Props(new Actor { + context.setReceiveTimeout(500 milliseconds) protected def receive = { case Tick ⇒ () case ReceiveTimeout ⇒ timeoutLatch.open } - }) + })) timeoutActor ! Tick @@ -53,17 +53,17 @@ class ReceiveTimeoutSpec extends AkkaSpec { val timeoutLatch = TestLatch() case object Tick - val timeoutActor = system.actorOf(new Actor { - context.receiveTimeout = Some(500 milliseconds) + val timeoutActor = system.actorOf(Props(new Actor { + context.setReceiveTimeout(500 milliseconds) protected def receive = { case Tick ⇒ () case ReceiveTimeout ⇒ count.incrementAndGet timeoutLatch.open - context.receiveTimeout = None + context.resetReceiveTimeout() } - }) + })) timeoutActor ! Tick @@ -75,11 +75,11 @@ class ReceiveTimeoutSpec extends AkkaSpec { "not receive timeout message when not specified" in { val timeoutLatch = TestLatch() - val timeoutActor = system.actorOf(new Actor { + val timeoutActor = system.actorOf(Props(new Actor { protected def receive = { case ReceiveTimeout ⇒ timeoutLatch.open } - }) + })) timeoutLatch.awaitTimeout(1 second) // timeout expected timeoutActor.stop() diff --git a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala index bca3a754c8..ceeb768b6c 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/SchedulerSpec.scala @@ -26,9 +26,9 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout "schedule more than once" in { case object Tick val countDownLatch = new CountDownLatch(3) - val tickActor = system.actorOf(new Actor { + val tickActor = system.actorOf(Props(new Actor { def receive = { case Tick ⇒ countDownLatch.countDown() } - }) + })) // run every 50 milliseconds collectCancellable(system.scheduler.schedule(0 milliseconds, 50 milliseconds, tickActor, Tick)) @@ -56,9 +56,9 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout "schedule once" in { case object Tick val countDownLatch = new CountDownLatch(3) - val tickActor = system.actorOf(new Actor { + val tickActor = system.actorOf(Props(new Actor { def receive = { case Tick ⇒ countDownLatch.countDown() } - }) + })) // run after 300 millisec collectCancellable(system.scheduler.scheduleOnce(300 milliseconds, tickActor, Tick)) @@ -81,9 +81,9 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout object Ping val ticks = new CountDownLatch(1) - val actor = system.actorOf(new Actor { + val actor = system.actorOf(Props(new Actor { def receive = { case Ping ⇒ ticks.countDown() } - }) + })) (1 to 10).foreach { i ⇒ val timeout = collectCancellable(system.scheduler.scheduleOnce(1 second, actor, Ping)) @@ -131,7 +131,7 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout case class Msg(ts: Long) - val actor = system.actorOf(new Actor { + val actor = system.actorOf(Props(new Actor { def receive = { case Msg(ts) ⇒ val now = System.nanoTime @@ -139,7 +139,7 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout if (now - ts < 10000000) throw new RuntimeException("Interval is too small: " + (now - ts)) ticks.countDown() } - }) + })) (1 to 300).foreach { i ⇒ collectCancellable(system.scheduler.scheduleOnce(10 milliseconds, actor, Msg(System.nanoTime))) @@ -154,11 +154,11 @@ class SchedulerSpec extends AkkaSpec with BeforeAndAfterEach with DefaultTimeout case object Msg - val actor = system.actorOf(new Actor { + val actor = system.actorOf(Props(new Actor { def receive = { case Msg ⇒ ticks.countDown() } - }) + })) val startTime = System.nanoTime() val cancellable = system.scheduler.schedule(1 second, 100 milliseconds, actor, Msg) diff --git a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorsSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorsSpec.scala index df4048a56e..8ad5bc641d 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorsSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/dispatch/DispatcherActorsSpec.scala @@ -1,7 +1,7 @@ package akka.actor.dispatch import java.util.concurrent.CountDownLatch -import akka.actor.Actor +import akka.actor._ import akka.testkit.AkkaSpec /** @@ -31,8 +31,8 @@ class DispatcherActorsSpec extends AkkaSpec { "not block fast actors by slow actors" in { val sFinished = new CountDownLatch(50) val fFinished = new CountDownLatch(10) - val s = system.actorOf(new SlowActor(sFinished)) - val f = system.actorOf(new FastActor(fFinished)) + val s = system.actorOf(Props(new SlowActor(sFinished))) + val f = system.actorOf(Props(new FastActor(fFinished))) // send a lot of stuff to s for (i ← 1 to 50) { diff --git a/akka-actor-tests/src/test/scala/akka/actor/routing/ListenerSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/routing/ListenerSpec.scala index 8f074a504c..ab149216a7 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/routing/ListenerSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/routing/ListenerSpec.scala @@ -16,13 +16,13 @@ class ListenerSpec extends AkkaSpec { val barLatch = TestLatch(2) val barCount = new AtomicInteger(0) - val broadcast = system.actorOf(new Actor with Listeners { + val broadcast = system.actorOf(Props(new Actor with Listeners { def receive = listenerManagement orElse { case "foo" ⇒ gossip("bar") } - }) + })) - def newListener = system.actorOf(new Actor { + def newListener = system.actorOf(Props(new Actor { def receive = { case "bar" ⇒ barCount.incrementAndGet @@ -30,7 +30,7 @@ class ListenerSpec extends AkkaSpec { case "foo" ⇒ fooLatch.countDown() } - }) + })) val a1 = newListener val a2 = newListener diff --git a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala index 2ef735b05f..44ddf4f8bc 100644 --- a/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/dispatch/FutureSpec.scala @@ -6,7 +6,7 @@ import org.scalacheck._ import org.scalacheck.Arbitrary._ import org.scalacheck.Prop._ import org.scalacheck.Gen._ -import akka.actor.{ Actor, ActorRef, Status } +import akka.actor._ import akka.testkit.{ EventFilter, filterEvents, filterException } import akka.util.duration._ import org.multiverse.api.latches.StandardLatch @@ -116,7 +116,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "from an Actor" that { "returns a result" must { behave like futureWithResult { test ⇒ - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val future = actor ? "Hello" future.await test(future, "World") @@ -126,7 +126,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "throws an exception" must { behave like futureWithException[RuntimeException] { test ⇒ filterException[RuntimeException] { - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val future = actor ? "Failure" future.await test(future, "Expected exception; to test fault-tolerance") @@ -139,8 +139,8 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "using flatMap with an Actor" that { "will return a result" must { behave like futureWithResult { test ⇒ - val actor1 = system.actorOf[TestActor] - val actor2 = system.actorOf(new Actor { def receive = { case s: String ⇒ sender ! s.toUpperCase } }) + val actor1 = system.actorOf(Props[TestActor]) + val actor2 = system.actorOf(Props(new Actor { def receive = { case s: String ⇒ sender ! s.toUpperCase } })) val future = actor1 ? "Hello" flatMap { case s: String ⇒ actor2 ? s } future.await test(future, "WORLD") @@ -151,8 +151,8 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "will throw an exception" must { behave like futureWithException[ArithmeticException] { test ⇒ filterException[ArithmeticException] { - val actor1 = system.actorOf[TestActor] - val actor2 = system.actorOf(new Actor { def receive = { case s: String ⇒ sender ! Status.Failure(new ArithmeticException("/ by zero")) } }) + val actor1 = system.actorOf(Props[TestActor]) + val actor2 = system.actorOf(Props(new Actor { def receive = { case s: String ⇒ sender ! Status.Failure(new ArithmeticException("/ by zero")) } })) val future = actor1 ? "Hello" flatMap { case s: String ⇒ actor2 ? s } future.await test(future, "/ by zero") @@ -164,8 +164,8 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "will throw a MatchError when matching wrong type" must { behave like futureWithException[MatchError] { test ⇒ filterException[MatchError] { - val actor1 = system.actorOf[TestActor] - val actor2 = system.actorOf(new Actor { def receive = { case s: String ⇒ sender ! s.toUpperCase } }) + val actor1 = system.actorOf(Props[TestActor]) + val actor2 = system.actorOf(Props(new Actor { def receive = { case s: String ⇒ sender ! s.toUpperCase } })) val future = actor1 ? "Hello" flatMap { case i: Int ⇒ actor2 ? i } future.await test(future, "World (of class java.lang.String)") @@ -180,12 +180,12 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "compose with for-comprehensions" in { filterException[ClassCastException] { - val actor = system.actorOf(new Actor { + val actor = system.actorOf(Props(new Actor { def receive = { case s: String ⇒ sender ! s.length case i: Int ⇒ sender ! (i * 2).toString } - }) + })) val future0 = actor ? "Hello" @@ -212,12 +212,12 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa filterException[MatchError] { case class Req[T](req: T) case class Res[T](res: T) - val actor = system.actorOf(new Actor { + val actor = system.actorOf(Props(new Actor { def receive = { case Req(s: String) ⇒ sender ! Res(s.length) case Req(i: Int) ⇒ sender ! Res((i * 2).toString) } - }) + })) val future1 = for { Res(a: Int) ← actor ? Req("Hello") @@ -257,7 +257,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa val future7 = future3 recover { case e: ArithmeticException ⇒ "You got ERROR" } - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val future8 = actor ? "Failure" val future9 = actor ? "Failure" recover { @@ -300,9 +300,9 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "fold" in { val actors = (1 to 10).toList map { _ ⇒ - system.actorOf(new Actor { + system.actorOf(Props(new Actor { def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait); sender.tell(add) } - }) + })) } val timeout = 10000 def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), timeout).mapTo[Int] } @@ -311,9 +311,9 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "fold by composing" in { val actors = (1 to 10).toList map { _ ⇒ - system.actorOf(new Actor { + system.actorOf(Props(new Actor { def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait); sender.tell(add) } - }) + })) } def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), 10000).mapTo[Int] } futures.foldLeft(Future(0))((fr, fa) ⇒ for (r ← fr; a ← fa) yield (r + a)).get must be(45) @@ -322,14 +322,14 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "fold with an exception" in { filterException[IllegalArgumentException] { val actors = (1 to 10).toList map { _ ⇒ - system.actorOf(new Actor { + system.actorOf(Props(new Actor { def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait) if (add == 6) sender ! Status.Failure(new IllegalArgumentException("shouldFoldResultsWithException: expected")) else sender.tell(add) } - }) + })) } val timeout = 10000 def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100), timeout).mapTo[Int] } @@ -358,9 +358,9 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "shouldReduceResults" in { val actors = (1 to 10).toList map { _ ⇒ - system.actorOf(new Actor { + system.actorOf(Props(new Actor { def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait); sender.tell(add) } - }) + })) } val timeout = 10000 def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 200), timeout).mapTo[Int] } @@ -370,14 +370,14 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "shouldReduceResultsWithException" in { filterException[IllegalArgumentException] { val actors = (1 to 10).toList map { _ ⇒ - system.actorOf(new Actor { + system.actorOf(Props(new Actor { def receive = { case (add: Int, wait: Int) ⇒ Thread.sleep(wait) if (add == 6) sender ! Status.Failure(new IllegalArgumentException("shouldFoldResultsWithException: expected")) else sender.tell(add) } - }) + })) } val timeout = 10000 def futures = actors.zipWithIndex map { case (actor: ActorRef, idx: Int) ⇒ actor.?((idx, idx * 100), timeout).mapTo[Int] } @@ -393,21 +393,21 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "receiveShouldExecuteOnComplete" in { val latch = new StandardLatch - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) actor ? "Hello" onResult { case "World" ⇒ latch.open } assert(latch.tryAwait(5, TimeUnit.SECONDS)) actor.stop() } "shouldTraverseFutures" in { - val oddActor = system.actorOf(new Actor { + val oddActor = system.actorOf(Props(new Actor { var counter = 1 def receive = { case 'GetNext ⇒ sender ! counter counter += 2 } - }) + })) val oddFutures = List.fill(100)(oddActor ? 'GetNext mapTo manifest[Int]) assert(Future.sequence(oddFutures).get.sum === 10000) @@ -461,7 +461,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa "futureComposingWithContinuations" in { import Future.flow - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val x = Future("Hello") val y = x flatMap (actor ? _) mapTo manifest[String] @@ -490,7 +490,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa filterException[ClassCastException] { import Future.flow - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val x = Future(3) val y = (actor ? "Hello").mapTo[Int] @@ -505,7 +505,7 @@ class FutureSpec extends AkkaSpec with Checkers with BeforeAndAfterAll with Defa filterException[ClassCastException] { import Future.flow - val actor = system.actorOf[TestActor] + val actor = system.actorOf(Props[TestActor]) val x = Future("Hello") val y = actor ? "Hello" mapTo manifest[Nothing] diff --git a/akka-actor-tests/src/test/scala/akka/performance/microbench/TellLatencyPerformanceSpec.scala b/akka-actor-tests/src/test/scala/akka/performance/microbench/TellLatencyPerformanceSpec.scala index 2de861c62c..c1de7702e3 100644 --- a/akka-actor-tests/src/test/scala/akka/performance/microbench/TellLatencyPerformanceSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/performance/microbench/TellLatencyPerformanceSpec.scala @@ -58,11 +58,11 @@ class TellLatencyPerformanceSpec extends PerformanceSpec { val latch = new CountDownLatch(numberOfClients) val repeatsPerClient = repeat / numberOfClients val clients = (for (i ← 0 until numberOfClients) yield { - val destination = system.actorOf[Destination] - val w4 = system.actorOf(new Waypoint(destination)) - val w3 = system.actorOf(new Waypoint(w4)) - val w2 = system.actorOf(new Waypoint(w3)) - val w1 = system.actorOf(new Waypoint(w2)) + val destination = system.actorOf(Props[Destination]) + val w4 = system.actorOf(Props(new Waypoint(destination))) + val w3 = system.actorOf(Props(new Waypoint(w4))) + val w2 = system.actorOf(Props(new Waypoint(w3))) + val w1 = system.actorOf(Props(new Waypoint(w2))) Props(new Client(w1, latch, repeatsPerClient, clientDelay.toMicros.intValue, stat)).withDispatcher(clientDispatcher) }).toList.map(system.actorOf(_)) @@ -133,4 +133,4 @@ object TellLatencyPerformanceSpec { } -} \ No newline at end of file +} diff --git a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala index 943718848a..1893732686 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/ActorPoolSpec.scala @@ -82,11 +82,11 @@ class ActorPoolSpec extends AkkaSpec with DefaultTimeout { }).withFaultHandler(faultHandler)) val successes = TestLatch(2) - val successCounter = system.actorOf(new Actor { + val successCounter = system.actorOf(Props(new Actor { def receive = { case "success" ⇒ successes.countDown() } - }) + })) implicit val replyTo = successCounter pool ! "a" diff --git a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala index fd51501142..ac940c8c2c 100644 --- a/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/routing/RoutingSpec.scala @@ -28,7 +28,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { "direct router" must { "be started when constructed" in { - val actor1 = system.actorOf[TestActor] + val actor1 = system.actorOf(Props[TestActor]) val props = RoutedProps(routerFactory = () ⇒ new DirectRouter, connectionManager = new LocalConnectionManager(List(actor1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -39,12 +39,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(1) val counter = new AtomicInteger(0) - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case _ ⇒ counter.incrementAndGet } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new DirectRouter, connectionManager = new LocalConnectionManager(List(connection1))) val routedActor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -60,12 +60,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(1) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new DirectRouter, connectionManager = new LocalConnectionManager(List(connection1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -82,7 +82,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { "round robin router" must { "be started when constructed" in { - val actor1 = system.actorOf[TestActor] + val actor1 = system.actorOf(Props[TestActor]) val props = RoutedProps(routerFactory = () ⇒ new RoundRobinRouter, connectionManager = new LocalConnectionManager(List(actor1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -104,12 +104,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { for (i ← 0 until connectionCount) { counters = counters :+ new AtomicInteger() - val connection = system.actorOf(new Actor { + val connection = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counters.get(i).get.addAndGet(msg) } - }) + })) connections = connections :+ connection } @@ -138,20 +138,20 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(2) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) } - }) + })) val counter2 = new AtomicInteger - val connection2 = system.actorOf(new Actor { + val connection2 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter2.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new RoundRobinRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -169,12 +169,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(1) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case _ ⇒ counter1.incrementAndGet() } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new RoundRobinRouter, connectionManager = new LocalConnectionManager(List(connection1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -191,7 +191,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { "be started when constructed" in { - val actor1 = system.actorOf[TestActor] + val actor1 = system.actorOf(Props[TestActor]) val props = RoutedProps(routerFactory = () ⇒ new RandomRouter, connectionManager = new LocalConnectionManager(List(actor1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -202,20 +202,20 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(2) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) } - }) + })) val counter2 = new AtomicInteger - val connection2 = system.actorOf(new Actor { + val connection2 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter2.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new RandomRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -233,12 +233,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(1) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case _ ⇒ counter1.incrementAndGet() } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new RandomRouter, connectionManager = new LocalConnectionManager(List(connection1))) val actor = new RoutedActorRef(system, props, impl.guardian, "foo") @@ -326,12 +326,12 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { for (i ← 0 until connectionCount) { counters = counters :+ new AtomicInteger() - val connection = system.actorOf(new Actor { + val connection = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counters.get(i).get.addAndGet(msg) } - }) + })) connections = connections :+ connection } @@ -359,20 +359,20 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new TestLatch(2) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) } - }) + })) val counter2 = new AtomicInteger - val connection2 = system.actorOf(new Actor { + val connection2 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter2.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new ScatterGatherFirstCompletedRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2))) @@ -389,7 +389,7 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { case class Stop(id: Option[Int] = None) - def newActor(id: Int, shudownLatch: Option[TestLatch] = None) = system.actorOf(new Actor { + def newActor(id: Int, shudownLatch: Option[TestLatch] = None) = system.actorOf(Props(new Actor { def receive = { case Stop(None) ⇒ self.stop() case Stop(Some(_id)) if (_id == id) ⇒ self.stop() @@ -400,13 +400,13 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { override def postStop = { shudownLatch foreach (_.countDown()) } - }) + })) } "broadcast router" must { "be started when constructed" in { - val actor1 = system.actorOf[TestActor] + val actor1 = system.actorOf(Props[TestActor]) val props = RoutedProps(routerFactory = () ⇒ new BroadcastRouter, connectionManager = new LocalConnectionManager(List(actor1))) val actor = new RoutedActorRef(system, props, system.asInstanceOf[ActorSystemImpl].guardian, "foo") @@ -417,20 +417,20 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(2) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) } - }) + })) val counter2 = new AtomicInteger - val connection2 = system.actorOf(new Actor { + val connection2 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter2.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new BroadcastRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2))) val actor = new RoutedActorRef(system, props, system.asInstanceOf[ActorSystemImpl].guardian, "foo") @@ -448,22 +448,22 @@ class RoutingSpec extends AkkaSpec with DefaultTimeout { val doneLatch = new CountDownLatch(2) val counter1 = new AtomicInteger - val connection1 = system.actorOf(new Actor { + val connection1 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter1.addAndGet(msg) sender ! "ack" } - }) + })) val counter2 = new AtomicInteger - val connection2 = system.actorOf(new Actor { + val connection2 = system.actorOf(Props(new Actor { def receive = { case "end" ⇒ doneLatch.countDown() case msg: Int ⇒ counter2.addAndGet(msg) } - }) + })) val props = RoutedProps(routerFactory = () ⇒ new BroadcastRouter, connectionManager = new LocalConnectionManager(List(connection1, connection2))) val actor = new RoutedActorRef(system, props, system.asInstanceOf[ActorSystemImpl].guardian, "foo") diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index df1bb0e6a5..2c7944a69e 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -188,12 +188,12 @@ trait Actor { def noContextError = throw new ActorInitializationException( - "\n\tYou cannot create an instance of " + getClass.getName + " explicitly using the constructor (new)." + + "\n\tYou cannot create an instance of [" + getClass.getName + "] explicitly using the constructor (new)." + "\n\tYou have to use one of the factory methods to create a new actor. Either use:" + - "\n\t\t'val actor = context.actorOf[MyActor]' (to create a supervised child actor from within an actor), or" + - "\n\t\t'val actor = system.actorOf(new MyActor(..))' (to create a top level actor from the ActorSystem), or" + - "\n\t\t'val actor = context.actorOf[MyActor]' (to create a supervised child actor from within an actor), or" + - "\n\t\t'val actor = system.actorOf(new MyActor(..))' (to create a top level actor from the ActorSystem)") + "\n\t\t'val actor = context.actorOf(Props[MyActor])' (to create a supervised child actor from within an actor), or" + + "\n\t\t'val actor = system.actorOf(Props(new MyActor(..)))' (to create a top level actor from the ActorSystem), or" + + "\n\t\t'val actor = context.actorOf(Props[MyActor])' (to create a supervised child actor from within an actor), or" + + "\n\t\t'val actor = system.actorOf(Props(new MyActor(..)))' (to create a top level actor from the ActorSystem)") if (contextStack.isEmpty) noContextError val c = contextStack.head diff --git a/akka-actor/src/main/scala/akka/actor/ActorCell.scala b/akka-actor/src/main/scala/akka/actor/ActorCell.scala index c17924c56c..33fc177de6 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorCell.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorCell.scala @@ -28,16 +28,16 @@ import java.io.{ NotSerializableException, ObjectOutputStream } * context.actorOf(props) * * // Scala - * context.actorOf[MyActor]("name") - * context.actorOf[MyActor] - * context.actorOf(new MyActor(...)) + * context.actorOf(Props[MyActor]("name") + * context.actorOf(Props[MyActor] + * context.actorOf(Props(new MyActor(...)) * * // Java * context.actorOf(classOf[MyActor]); - * context.actorOf(new Creator() { + * context.actorOf(Props(new Creator() { * public MyActor create() { ... } * }); - * context.actorOf(new Creator() { + * context.actorOf(Props(new Creator() { * public MyActor create() { ... } * }, "name"); * }}} @@ -59,7 +59,12 @@ trait ActorContext extends ActorRefFactory { * When specified, the receive function should be able to handle a 'ReceiveTimeout' message. * 1 millisecond is the minimum supported timeout. */ - def receiveTimeout_=(timeout: Option[Duration]): Unit + def setReceiveTimeout(timeout: Duration): Unit + + /** + * Resets the current receive timeout. + */ + def resetReceiveTimeout(): Unit /** * Changes the Actor's behavior to become the new 'Receive' (PartialFunction[Any, Unit]) handler. @@ -68,19 +73,29 @@ trait ActorContext extends ActorRefFactory { */ def become(behavior: Actor.Receive, discardOld: Boolean = true): Unit - def hotswap: Stack[PartialFunction[Any, Unit]] - /** * Reverts the Actor behavior to the previous one in the hotswap stack. */ def unbecome(): Unit + /** + * Returns the current message envelope. + */ def currentMessage: Envelope - def currentMessage_=(invocation: Envelope): Unit + /** + * Returns a stack with the hotswapped behaviors (as Scala PartialFunction). + */ + def hotswap: Stack[PartialFunction[Any, Unit]] + /** + * Returns the sender 'ActorRef' of the current message. + */ def sender: ActorRef + /** + * Returns all supervised children. + */ def children: Iterable[ActorRef] /** @@ -99,16 +114,19 @@ trait ActorContext extends ActorRefFactory { */ implicit def system: ActorSystem + /** + * Returns the supervising parent ActorRef. + */ def parent: ActorRef /** - * Registers this actor as a Monitor for the provided ActorRef + * Registers this actor as a Monitor for the provided ActorRef. * @return the provided ActorRef */ def watch(subject: ActorRef): ActorRef /** - * Unregisters this actor as Monitor for the provided ActorRef + * Unregisters this actor as Monitor for the provided ActorRef. * @return the provided ActorRef */ def unwatch(subject: ActorRef): ActorRef @@ -118,25 +136,13 @@ trait ActorContext extends ActorRefFactory { } trait UntypedActorContext extends ActorContext { + /** * Returns an unmodifiable Java Collection containing the linked actors, * please note that the backing map is thread-safe but not immutable */ def getChildren(): java.lang.Iterable[ActorRef] - /** - * Gets the current receive timeout - * When specified, the receive method should be able to handle a 'ReceiveTimeout' message. - */ - def getReceiveTimeout: Option[Duration] - - /** - * Defines the default timeout for an initial receive invocation. - * When specified, the receive function should be able to handle a 'ReceiveTimeout' message. - * 1 millisecond is the minimum supported timeout. - */ - def setReceiveTimeout(timeout: Duration): Unit - /** * Changes the Actor's behavior to become the new 'Procedure' handler. * Puts the behavior on top of the hotswap stack. @@ -190,7 +196,9 @@ private[akka] final class ActorCell( override def receiveTimeout: Option[Duration] = if (receiveTimeoutData._1 > 0) Some(Duration(receiveTimeoutData._1, MILLISECONDS)) else None - override def receiveTimeout_=(timeout: Option[Duration]): Unit = { + override def setReceiveTimeout(timeout: Duration): Unit = setReceiveTimeout(Some(timeout)) + + def setReceiveTimeout(timeout: Option[Duration]): Unit = { val timeoutMs = timeout match { case None ⇒ -1L case Some(duration) ⇒ @@ -203,22 +211,14 @@ private[akka] final class ActorCell( receiveTimeoutData = (timeoutMs, receiveTimeoutData._2) } + override def resetReceiveTimeout(): Unit = setReceiveTimeout(None) + /** * In milliseconds */ var receiveTimeoutData: (Long, Cancellable) = if (_receiveTimeout.isDefined) (_receiveTimeout.get.toMillis, emptyCancellable) else emptyReceiveTimeoutData - /** - * UntypedActorContext impl - */ - def getReceiveTimeout: Option[Duration] = receiveTimeout - - /** - * UntypedActorContext impl - */ - def setReceiveTimeout(timeout: Duration): Unit = receiveTimeout = Some(timeout) - var childrenRefs: TreeMap[String, ChildRestartStats] = emptyChildrenRefs private def _actorOf(props: Props, name: String): ActorRef = { @@ -391,7 +391,7 @@ private[akka] final class ActorCell( def resume(): Unit = dispatcher resume this def terminate() { - receiveTimeout = None + setReceiveTimeout(None) cancelReceiveTimeout val c = children diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index a5253c440b..abd88f31a5 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -25,21 +25,21 @@ import scala.annotation.tailrec *
  *   import Actor._
  *
- *   val actor = actorOf[MyActor]
+ *   val actor = actorOf(Props[MyActor]
  *   actor ! message
  *   actor.stop()
  * 
* * You can also create and start actors like this: *
- *   val actor = actorOf[MyActor]
+ *   val actor = actorOf(Props[MyActor]
  * 
* * Here is an example on how to create an actor with a non-default constructor. *
  *   import Actor._
  *
- *   val actor = actorOf(new MyActor(...))
+ *   val actor = actorOf(Props(new MyActor(...))
  *   actor ! message
  *   actor.stop()
  * 
@@ -455,7 +455,7 @@ class AskActorRef( } override def ?(message: Any)(implicit timeout: Timeout): Future[Any] = - new KeptPromise[Any](Left(new UnsupportedOperationException("Ask/? is not supported for %s".format(getClass.getName))))(dispatcher) + new KeptPromise[Any](Left(new UnsupportedOperationException("Ask/? is not supported for [%s]".format(getClass.getName))))(dispatcher) override def isTerminated = result.isCompleted || result.isExpired diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index d68a1349f0..f038d430d0 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -164,82 +164,6 @@ trait ActorRefFactory { */ def actorOf(props: Props, name: String): ActorRef - /** - * Create new actor of the given type as child of this context and give it an automatically - * generated name (currently similar to base64-encoded integer count, - * reversed and with “$” prepended, may change in the future). The type must have - * a no-arg constructor which will be invoked using reflection. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf[T <: Actor](implicit m: Manifest[T]): ActorRef = actorOf(Props(m.erasure.asInstanceOf[Class[_ <: Actor]])) - - /** - * Create new actor of the given type as child of this context with the given name, which must - * not be null, empty or start with “$”. If the given name is already in use, - * and `InvalidActorNameException` is thrown. The type must have - * a no-arg constructor which will be invoked using reflection. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf[T <: Actor](name: String)(implicit m: Manifest[T]): ActorRef = - actorOf(Props(m.erasure.asInstanceOf[Class[_ <: Actor]]), name) - - /** - * Create new actor of the given class as child of this context and give it an automatically - * generated name (currently similar to base64-encoded integer count, - * reversed and with “$” prepended, may change in the future). The class must have - * a no-arg constructor which will be invoked using reflection. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf[T <: Actor](clazz: Class[T]): ActorRef = actorOf(Props(clazz)) - - /** - * Create new actor as child of this context and give it an automatically - * generated name (currently similar to base64-encoded integer count, - * reversed and with “$” prepended, may change in the future). Use this - * method to pass constructor arguments to the [[akka.actor.Actor]] while using - * only default [[akka.actor.Props]]; otherwise refer to `actorOf(Props)`. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf(factory: ⇒ Actor): ActorRef = actorOf(Props(() ⇒ factory)) - - /** - * ''Java API'': Create new actor as child of this context and give it an - * automatically generated name (currently similar to base64-encoded integer - * count, reversed and with “$” prepended, may change in the future). - * - * Identical to `actorOf(Props(() => creator.create()))`. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf(creator: UntypedActorFactory): ActorRef = actorOf(Props(() ⇒ creator.create())) - - /** - * ''Java API'': Create new actor as child of this context with the given name, which must - * not be null, empty or start with “$”. If the given name is already in use, - * and `InvalidActorNameException` is thrown. - * - * Identical to `actorOf(Props(() => creator.create()), name)`. - * - * When invoked on ActorSystem, this method sends a message to the guardian - * actor and blocks waiting for a reply, see `akka.actor.creation-timeout` in - * the `reference.conf`. - */ - def actorOf(creator: UntypedActorFactory, name: String): ActorRef = actorOf(Props(() ⇒ creator.create()), name) - /** * Look-up an actor by path; if it does not exist, returns a reference to * the dead-letter mailbox of the [[akka.actor.ActorSystem]]. If the path @@ -388,14 +312,14 @@ class LocalActorRefProvider( override def !(message: Any)(implicit sender: ActorRef = null): Unit = stopped.ifOff(message match { case Failed(ex) if sender ne null ⇒ causeOfTermination = Some(ex); sender.stop() - case _ ⇒ log.error(this + " received unexpected message " + message) + case _ ⇒ log.error(this + " received unexpected message [" + message + "]") }) override def sendSystemMessage(message: SystemMessage): Unit = stopped ifOff { message match { case Supervise(child) ⇒ // TODO register child in some map to keep track of it and enable shutdown after all dead case ChildTerminated(child) ⇒ stop() - case _ ⇒ log.error(this + " received unexpected system message " + message) + case _ ⇒ log.error(this + " received unexpected system message [" + message + "]") } } } @@ -538,7 +462,7 @@ class LocalActorRefProvider( actorOf(system, RoutedProps(routerFactory = routerFactory, connectionManager = new LocalConnectionManager(connections)), supervisor, path.name) - case unknown ⇒ throw new Exception("Don't know how to create this actor ref! Why? Got: " + unknown) + case unknown ⇒ throw new Exception("Don't know how to create this Actor - cause [" + unknown + "]") } } diff --git a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala index fb769b2644..66a211def8 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSystem.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSystem.scala @@ -104,8 +104,7 @@ object ActorSystem { val SchedulerTicksPerWheel = getInt("akka.scheduler.ticksPerWheel") if (ConfigVersion != Version) - throw new ConfigurationException("Akka JAR version [" + Version + - "] does not match the provided config version [" + ConfigVersion + "]") + throw new ConfigurationException("Akka JAR version [" + Version + "] does not match the provided config version [" + ConfigVersion + "]") override def toString: String = config.root.render } @@ -168,16 +167,16 @@ object ActorSystem { * system.actorOf(props) * * // Scala - * system.actorOf[MyActor]("name") - * system.actorOf[MyActor] - * system.actorOf(new MyActor(...)) + * system.actorOf(Props[MyActor]("name") + * system.actorOf(Props[MyActor] + * system.actorOf(Props(new MyActor(...)) * * // Java * system.actorOf(classOf[MyActor]); - * system.actorOf(new Creator() { + * system.actorOf(Props(new Creator() { * public MyActor create() { ... } * }); - * system.actorOf(new Creator() { + * system.actorOf(Props(new Creator() { * public MyActor create() { ... } * }, "name"); * }}} @@ -328,7 +327,7 @@ abstract class ActorSystem extends ActorRefFactory { class ActorSystemImpl(val name: String, applicationConfig: Config) extends ActorSystem { if (!name.matches("""^\w+$""")) - throw new IllegalArgumentException("invalid ActorSystem name '" + name + "', must contain only word characters (i.e. [a-zA-Z_0-9])") + throw new IllegalArgumentException("invalid ActorSystem name [" + name + "], must contain only word characters (i.e. [a-zA-Z_0-9])") import ActorSystem._ @@ -465,8 +464,8 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor } /* - * This is called after the last actor has signaled its termination, i.e. - * after the last dispatcher has had its chance to schedule its shutdown + * This is called after the last actor has signaled its termination, i.e. + * after the last dispatcher has had its chance to schedule its shutdown * action. */ protected def stopScheduler(): Unit = scheduler match { @@ -493,7 +492,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor extensions.putIfAbsent(ext, inProcessOfRegistration) match { // Signal that registration is in process case null ⇒ try { // Signal was successfully sent ext.createExtension(this) match { // Create and initialize the extension - case null ⇒ throw new IllegalStateException("Extension instance created as null for Extension: " + ext) + case null ⇒ throw new IllegalStateException("Extension instance created as 'null' for extension [" + ext + "]") case instance ⇒ extensions.replace(ext, inProcessOfRegistration, instance) //Replace our in process signal with the initialized extension instance //Profit! @@ -512,7 +511,7 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor } def extension[T <: Extension](ext: ExtensionId[T]): T = findExtension(ext) match { - case null ⇒ throw new IllegalArgumentException("Trying to get non-registered extension " + ext) + case null ⇒ throw new IllegalArgumentException("Trying to get non-registered extension [" + ext + "]") case some ⇒ some.asInstanceOf[T] } @@ -525,8 +524,8 @@ class ActorSystemImpl(val name: String, applicationConfig: Config) extends Actor getObjectFor[AnyRef](fqcn).fold(_ ⇒ createInstance[AnyRef](fqcn, noParams, noArgs), Right(_)) match { case Right(p: ExtensionIdProvider) ⇒ registerExtension(p.lookup()); case Right(p: ExtensionId[_]) ⇒ registerExtension(p); - case Right(other) ⇒ log.error("'{}' is not an ExtensionIdProvider or ExtensionId, skipping...", fqcn) - case Left(problem) ⇒ log.error(problem, "While trying to load extension '{}', skipping...", fqcn) + case Right(other) ⇒ log.error("[{}] is not an 'ExtensionIdProvider' or 'ExtensionId', skipping...", fqcn) + case Left(problem) ⇒ log.error(problem, "While trying to load extension [{}], skipping...", fqcn) } } diff --git a/akka-actor/src/main/scala/akka/actor/IO.scala b/akka-actor/src/main/scala/akka/actor/IO.scala index 1a92679c4b..1551eef2ec 100644 --- a/akka-actor/src/main/scala/akka/actor/IO.scala +++ b/akka-actor/src/main/scala/akka/actor/IO.scala @@ -193,7 +193,7 @@ trait IO { private def run() { _next match { case ByteStringLength(continuation, handle, message, waitingFor) ⇒ - context.currentMessage = message + context.asInstanceOf[ActorCell].currentMessage = message val st = state(handle) if (st.readBytes.length >= waitingFor) { val bytes = st.readBytes.take(waitingFor) //.compact @@ -202,7 +202,7 @@ trait IO { run() } case bsd @ ByteStringDelimited(continuation, handle, message, delimiter, inclusive, scanned) ⇒ - context.currentMessage = message + context.asInstanceOf[ActorCell].currentMessage = message val st = state(handle) val idx = st.readBytes.indexOfSlice(delimiter, scanned) if (idx >= 0) { @@ -215,7 +215,7 @@ trait IO { _next = bsd.copy(scanned = math.min(idx - delimiter.length, 0)) } case ByteStringAny(continuation, handle, message) ⇒ - context.currentMessage = message + context.asInstanceOf[ActorCell].currentMessage = message val st = state(handle) if (st.readBytes.length > 0) { val bytes = st.readBytes //.compact diff --git a/akka-actor/src/main/scala/akka/actor/Props.scala b/akka-actor/src/main/scala/akka/actor/Props.scala index c9b28e4fa4..323c338196 100644 --- a/akka-actor/src/main/scala/akka/actor/Props.scala +++ b/akka-actor/src/main/scala/akka/actor/Props.scala @@ -81,6 +81,25 @@ case class Props(creator: () ⇒ Actor = Props.defaultCreator, @transient dispatcher: MessageDispatcher = Props.defaultDispatcher, timeout: Timeout = Props.defaultTimeout, faultHandler: FaultHandlingStrategy = Props.defaultFaultHandler) { + + /** + * Java API + */ + def this(factory: UntypedActorFactory) = this( + creator = () ⇒ factory.create(), + dispatcher = Props.defaultDispatcher, + timeout = Props.defaultTimeout, + faultHandler = Props.defaultFaultHandler) + + /** + * Java API + */ + def this(actorClass: Class[_ <: Actor]) = this( + creator = () ⇒ actorClass.newInstance, + dispatcher = Props.defaultDispatcher, + timeout = Props.defaultTimeout, + faultHandler = Props.defaultFaultHandler) + /** * No-args constructor that sets all the default values * Java API diff --git a/akka-camel-typed/src/test/scala/akka/camel/TypedConsumerPublishRequestorTest.scala b/akka-camel-typed/src/test/scala/akka/camel/TypedConsumerPublishRequestorTest.scala index 9d034b86fd..358bedc070 100644 --- a/akka-camel-typed/src/test/scala/akka/camel/TypedConsumerPublishRequestorTest.scala +++ b/akka-camel-typed/src/test/scala/akka/camel/TypedConsumerPublishRequestorTest.scala @@ -21,10 +21,10 @@ class TypedConsumerPublishRequestorTest extends JUnitSuite { @Before def setUp{ - publisher = actorOf(new TypedConsumerPublisherMock) - requestor = actorOf(new TypedConsumerPublishRequestor) + publisher = actorOf(Props(new TypedConsumerPublisherMock) + requestor = actorOf(Props(new TypedConsumerPublishRequestor) requestor ! InitPublishRequestor(publisher) - consumer = actorOf(new Actor with Consumer { + consumer = actorOf(Props(new Actor with Consumer { def endpointUri = "mock:test" protected def receive = null }) diff --git a/akka-camel/src/test/scala/akka/camel/ConsumerPublishRequestorTest.scala b/akka-camel/src/test/scala/akka/camel/ConsumerPublishRequestorTest.scala index e52295e26b..f77cec4c0b 100644 --- a/akka-camel/src/test/scala/akka/camel/ConsumerPublishRequestorTest.scala +++ b/akka-camel/src/test/scala/akka/camel/ConsumerPublishRequestorTest.scala @@ -18,10 +18,10 @@ class ConsumerPublishRequestorTest extends JUnitSuite { @Before def setUp{ - publisher = actorOf(new ConsumerPublisherMock) - requestor = actorOf(new ConsumerPublishRequestor) + publisher = actorOf(Props(new ConsumerPublisherMock) + requestor = actorOf(Props(new ConsumerPublishRequestor) requestor ! InitPublishRequestor(publisher) - consumer = actorOf(new Actor with Consumer { + consumer = actorOf(Props(new Actor with Consumer { def endpointUri = "mock:test" protected def receive = null }).asInstanceOf[LocalActorRef] diff --git a/akka-camel/src/test/scala/akka/camel/ConsumerRegisteredTest.scala b/akka-camel/src/test/scala/akka/camel/ConsumerRegisteredTest.scala index 5003413d42..2289b5a3d4 100644 --- a/akka-camel/src/test/scala/akka/camel/ConsumerRegisteredTest.scala +++ b/akka-camel/src/test/scala/akka/camel/ConsumerRegisteredTest.scala @@ -9,21 +9,21 @@ class ConsumerRegisteredTest extends JUnitSuite { @Test def shouldCreateSomeNonBlockingPublishRequestFromConsumer = { - val c = Actor.actorOf[ConsumerActor1] + val c = Actor.actorOf(Props[ConsumerActor1] val event = ConsumerActorRegistered.eventFor(c) assert(event === Some(ConsumerActorRegistered(c, consumerOf(c)))) } @Test def shouldCreateSomeBlockingPublishRequestFromConsumer = { - val c = Actor.actorOf[ConsumerActor2] + val c = Actor.actorOf(Props[ConsumerActor2] val event = ConsumerActorRegistered.eventFor(c) assert(event === Some(ConsumerActorRegistered(c, consumerOf(c)))) } @Test def shouldCreateNoneFromConsumer = { - val event = ConsumerActorRegistered.eventFor(Actor.actorOf[PlainActor]) + val event = ConsumerActorRegistered.eventFor(Actor.actorOf(Props[PlainActor]) assert(event === None) } diff --git a/akka-camel/src/test/scala/akka/camel/ConsumerScalaTest.scala b/akka-camel/src/test/scala/akka/camel/ConsumerScalaTest.scala index efe7d6aee1..47dbdbba54 100644 --- a/akka-camel/src/test/scala/akka/camel/ConsumerScalaTest.scala +++ b/akka-camel/src/test/scala/akka/camel/ConsumerScalaTest.scala @@ -27,7 +27,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher service = CamelServiceFactory.createCamelService // register test consumer before registering the publish requestor // and before starting the CamelService (registry is scanned for consumers) - actorOf(new TestConsumer("direct:publish-test-1")) + actorOf(Props(new TestConsumer("direct:publish-test-1")) service.registerPublishRequestor service.awaitEndpointActivation(1) { service.start @@ -54,7 +54,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher "started" must { "support an in-out message exchange via its endpoint" in { service.awaitEndpointActivation(1) { - consumer = actorOf(new TestConsumer("direct:publish-test-2")) + consumer = actorOf(Props(new TestConsumer("direct:publish-test-2")) } must be(true) mandatoryTemplate.requestBody("direct:publish-test-2", "msg2") must equal("received msg2") } @@ -119,7 +119,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher "activated with a custom error handler" must { "handle thrown exceptions by generating a custom response" in { service.awaitEndpointActivation(1) { - actorOf[ErrorHandlingConsumer] + actorOf(Props[ErrorHandlingConsumer] } must be(true) mandatoryTemplate.requestBody("direct:error-handler-test", "hello") must equal("error: hello") @@ -128,7 +128,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher "activated with a custom redelivery handler" must { "handle thrown exceptions by redelivering the initial message" in { service.awaitEndpointActivation(1) { - actorOf[RedeliveringConsumer] + actorOf(Props[RedeliveringConsumer] } must be(true) mandatoryTemplate.requestBody("direct:redelivery-test", "hello") must equal("accepted: hello") @@ -143,7 +143,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher var consumer: ActorRef = null service.awaitEndpointActivation(1) { - consumer = actorOf(new TestAckConsumer("direct:system-ack-test")) + consumer = actorOf(Props(new TestAckConsumer("direct:system-ack-test")) } must be(true) val endpoint = mandatoryContext.getEndpoint("direct:system-ack-test", classOf[DirectEndpoint]) @@ -169,19 +169,19 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher "A supervised consumer" must { "be able to reply during receive" in { - val consumer = Actor.actorOf(new SupervisedConsumer("reply-channel-test-1")) + val consumer = Actor.actorOf(Props(new SupervisedConsumer("reply-channel-test-1")) (consumer ? "succeed").get must equal("ok") } "be able to reply on failure during preRestart" in { - val consumer = Actor.actorOf(new SupervisedConsumer("reply-channel-test-2")) + val consumer = Actor.actorOf(Props(new SupervisedConsumer("reply-channel-test-2")) val supervisor = Supervisor( SupervisorConfig( OneForOneStrategy(List(classOf[Exception]), 2, 10000), Supervise(consumer, Permanent) :: Nil)) val latch = new CountDownLatch(1) - val sender = Actor.actorOf(new Sender("pr", latch)) + val sender = Actor.actorOf(Props(new Sender("pr", latch)) consumer.!("fail")(Some(sender)) latch.await(5, TimeUnit.SECONDS) must be(true) @@ -195,7 +195,7 @@ class ConsumerScalaTest extends WordSpec with BeforeAndAfterAll with MustMatcher Supervise(consumer, Temporary) :: Nil)) val latch = new CountDownLatch(1) - val sender = Actor.actorOf(new Sender("ps", latch)) + val sender = Actor.actorOf(Props(new Sender("ps", latch)) consumer.!("fail")(Some(sender)) latch.await(5, TimeUnit.SECONDS) must be(true) diff --git a/akka-camel/src/test/scala/akka/camel/ProducerFeatureTest.scala b/akka-camel/src/test/scala/akka/camel/ProducerFeatureTest.scala index c2614d2263..a3c67064f8 100644 --- a/akka-camel/src/test/scala/akka/camel/ProducerFeatureTest.scala +++ b/akka-camel/src/test/scala/akka/camel/ProducerFeatureTest.scala @@ -31,7 +31,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message and receive normal response") { given("a registered two-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-2", true)) + val producer = actorOf(Props(new TestProducer("direct:producer-test-2", true)) when("a test message is sent to the producer with ?") val message = Message("test", Map(Message.MessageExchangeId -> "123")) @@ -44,7 +44,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message and receive failure response") { given("a registered two-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-2")) + val producer = actorOf(Props(new TestProducer("direct:producer-test-2")) when("a test message causing an exception is sent to the producer with ?") val message = Message("fail", Map(Message.MessageExchangeId -> "123")) @@ -59,7 +59,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message oneway") { given("a registered one-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-1", true) with Oneway) + val producer = actorOf(Props(new TestProducer("direct:producer-test-1", true) with Oneway) when("a test message is sent to the producer with !") mockEndpoint.expectedBodiesReceived("TEST") @@ -71,7 +71,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message twoway without sender reference") { given("a registered two-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-1")) + val producer = actorOf(Props(new TestProducer("direct:producer-test-1")) when("a test message is sent to the producer with !") mockEndpoint.expectedBodiesReceived("test") @@ -86,7 +86,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message and receive normal response") { given("a registered two-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-3")) + val producer = actorOf(Props(new TestProducer("direct:producer-test-3")) when("a test message is sent to the producer with ?") val message = Message("test", Map(Message.MessageExchangeId -> "123")) @@ -98,7 +98,7 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message and receive failure response") { given("a registered two-way producer") - val producer = actorOf(new TestProducer("direct:producer-test-3")) + val producer = actorOf(Props(new TestProducer("direct:producer-test-3")) when("a test message causing an exception is sent to the producer with ?") val message = Message("fail", Map(Message.MessageExchangeId -> "123")) @@ -116,8 +116,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward normal response to a replying target actor and receive response") { given("a registered two-way producer configured with a forward target") - val target = actorOf[ReplyingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-2", target)) + val target = actorOf(Props[ReplyingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-2", target)) when("a test message is sent to the producer with ?") val message = Message("test", Map(Message.MessageExchangeId -> "123")) @@ -130,8 +130,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward failure response to a replying target actor and receive response") { given("a registered two-way producer configured with a forward target") - val target = actorOf[ReplyingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-2", target)) + val target = actorOf(Props[ReplyingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-2", target)) when("a test message causing an exception is sent to the producer with ?") val message = Message("fail", Map(Message.MessageExchangeId -> "123")) @@ -146,8 +146,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward normal response to a producing target actor and produce response to direct:forward-test-1") { given("a registered one-way producer configured with a forward target") - val target = actorOf[ProducingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-2", target)) + val target = actorOf(Props[ProducingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-2", target)) when("a test message is sent to the producer with !") mockEndpoint.expectedBodiesReceived("received test") @@ -159,8 +159,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward failure response to a producing target actor and produce response to direct:forward-test-1") { given("a registered one-way producer configured with a forward target") - val target = actorOf[ProducingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-2", target)) + val target = actorOf(Props[ProducingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-2", target)) when("a test message causing an exception is sent to the producer with !") mockEndpoint.expectedMessageCount(1) @@ -176,8 +176,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward normal response to a replying target actor and receive response") { given("a registered two-way producer configured with a forward target") - val target = actorOf[ReplyingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-3", target)) + val target = actorOf(Props[ReplyingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-3", target)) when("a test message is sent to the producer with ?") val message = Message("test", Map(Message.MessageExchangeId -> "123")) @@ -190,8 +190,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward failure response to a replying target actor and receive response") { given("a registered two-way producer configured with a forward target") - val target = actorOf[ReplyingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-3", target)) + val target = actorOf(Props[ReplyingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-3", target)) when("a test message causing an exception is sent to the producer with ?") val message = Message("fail", Map(Message.MessageExchangeId -> "123")) @@ -206,8 +206,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward normal response to a producing target actor and produce response to direct:forward-test-1") { given("a registered one-way producer configured with a forward target") - val target = actorOf[ProducingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-3", target)) + val target = actorOf(Props[ProducingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-3", target)) when("a test message is sent to the producer with !") mockEndpoint.expectedBodiesReceived("received test") @@ -219,8 +219,8 @@ class ProducerFeatureTest extends FeatureSpec with BeforeAndAfterAll with Before scenario("produce message, forward failure response to a producing target actor and produce response to direct:forward-test-1") { given("a registered one-way producer configured with a forward target") - val target = actorOf[ProducingForwardTarget] - val producer = actorOf(new TestForwarder("direct:producer-test-3", target)) + val target = actorOf(Props[ProducingForwardTarget] + val producer = actorOf(Props(new TestForwarder("direct:producer-test-3", target)) when("a test message causing an exception is sent to the producer with !") mockEndpoint.expectedMessageCount(1) @@ -271,7 +271,7 @@ object ProducerFeatureTest { } class TestRoute extends RouteBuilder { - val responder = actorOf[TestResponder] + val responder = actorOf(Props[TestResponder] def configure { from("direct:forward-test-1").to("mock:mock") // for one-way messaging tests diff --git a/akka-camel/src/test/scala/akka/camel/component/ActorComponentFeatureTest.scala b/akka-camel/src/test/scala/akka/camel/component/ActorComponentFeatureTest.scala index 24fc306268..a86577e92b 100644 --- a/akka-camel/src/test/scala/akka/camel/component/ActorComponentFeatureTest.scala +++ b/akka-camel/src/test/scala/akka/camel/component/ActorComponentFeatureTest.scala @@ -33,7 +33,7 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with import CamelContextManager.mandatoryTemplate scenario("one-way communication") { - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get mandatoryTemplate.sendBody("actor:uuid:%s" format actor.uuid, "Martin") assert(latch.await(5000, TimeUnit.MILLISECONDS)) @@ -42,7 +42,7 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with } scenario("two-way communication") { - val actor = actorOf[Tester2] + val actor = actorOf(Props[Tester2] assert(mandatoryTemplate.requestBody("actor:uuid:%s" format actor.uuid, "Martin") === "Hello Martin") } @@ -70,7 +70,7 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with import CamelContextManager.mandatoryTemplate scenario("one-way communication") { - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get mandatoryTemplate.sendBody("actor:%s" format actor.address, "Martin") assert(latch.await(5000, TimeUnit.MILLISECONDS)) @@ -79,12 +79,12 @@ class ActorComponentFeatureTest extends FeatureSpec with BeforeAndAfterAll with } scenario("two-way communication") { - val actor = actorOf[Tester2] + val actor = actorOf(Props[Tester2] assert(mandatoryTemplate.requestBody("actor:%s" format actor.address, "Martin") === "Hello Martin") } scenario("two-way communication via a custom route") { - val actor = actorOf[CustomIdActor]("custom-id") + val actor = actorOf(Props[CustomIdActor]("custom-id") assert(mandatoryTemplate.requestBody("direct:custom-id-test-1", "Martin") === "Received Martin") assert(mandatoryTemplate.requestBody("direct:custom-id-test-2", "Martin") === "Received Martin") } @@ -113,8 +113,8 @@ object ActorComponentFeatureTest { } class TestRoute extends RouteBuilder { - val failWithMessage = actorOf[FailWithMessage] - val failWithException = actorOf[FailWithException] + val failWithMessage = actorOf(Props[FailWithMessage] + val failWithException = actorOf(Props[FailWithException] def configure { from("direct:custom-id-test-1").to("actor:custom-id") from("direct:custom-id-test-2").to("actor:id:custom-id") diff --git a/akka-camel/src/test/scala/akka/camel/component/ActorProducerTest.scala b/akka-camel/src/test/scala/akka/camel/component/ActorProducerTest.scala index f8e4aeec0a..31cbd33b0e 100644 --- a/akka-camel/src/test/scala/akka/camel/component/ActorProducerTest.scala +++ b/akka-camel/src/test/scala/akka/camel/component/ActorProducerTest.scala @@ -23,7 +23,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorWithSyncProcessor = { - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:uuid:%s" format actor.uuid) val exchange = endpoint.createExchange(ExchangePattern.InOnly) @@ -38,7 +38,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorWithAsyncProcessor = { - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:uuid:%s" format actor.uuid) val exchange = endpoint.createExchange(ExchangePattern.InOnly) @@ -53,7 +53,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorAndReceiveResponseWithSyncProcessor = { - val actor = actorOf(new Tester2 { + val actor = actorOf(Props(new Tester2 { override def response(msg: Message) = Message(super.response(msg), Map("k2" -> "v2")) }) val endpoint = actorEndpoint("actor:uuid:%s" format actor.uuid) @@ -67,7 +67,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorAndReceiveResponseWithAsyncProcessor = { - val actor = actorOf(new Tester2 { + val actor = actorOf(Props(new Tester2 { override def response(msg: Message) = Message(super.response(msg), Map("k2" -> "v2")) }) val completion = expectAsyncCompletion @@ -83,7 +83,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorAndReceiveFailureWithAsyncProcessor = { - val actor = actorOf(new Tester2 { + val actor = actorOf(Props(new Tester2 { override def response(msg: Message) = Failure(new Exception("testmsg"), Map("k3" -> "v3")) }) val completion = expectAsyncCompletion @@ -100,7 +100,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldSendMessageToActorAndReceiveAckWithAsyncProcessor = { - val actor = actorOf(new Tester2 { + val actor = actorOf(Props(new Tester2 { override def response(msg: Message) = akka.camel.Ack }) val completion = expectAsyncCompletion @@ -115,8 +115,8 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldDynamicallyRouteMessageToActorWithDefaultId = { - val actor1 = actorOf[Tester1]("x") - val actor2 = actorOf[Tester1]("y") + val actor1 = actorOf(Props[Tester1]("x") + val actor2 = actorOf(Props[Tester1]("y") actor1 actor2 val latch1 = (actor1 ? SetExpectedMessageCount(1)).as[CountDownLatch].get @@ -139,8 +139,8 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldDynamicallyRouteMessageToActorWithoutDefaultId = { - val actor1 = actorOf[Tester1]("x") - val actor2 = actorOf[Tester1]("y") + val actor1 = actorOf(Props[Tester1]("x") + val actor2 = actorOf(Props[Tester1]("y") actor1 actor2 val latch1 = (actor1 ? SetExpectedMessageCount(1)).as[CountDownLatch].get @@ -164,8 +164,8 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldDynamicallyRouteMessageToActorWithDefaultUuid = { - val actor1 = actorOf[Tester1] - val actor2 = actorOf[Tester1] + val actor1 = actorOf(Props[Tester1] + val actor2 = actorOf(Props[Tester1] val latch1 = (actor1 ? SetExpectedMessageCount(1)).as[CountDownLatch].get val latch2 = (actor2 ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:uuid:%s" format actor1.uuid) @@ -186,8 +186,8 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldDynamicallyRouteMessageToActorWithoutDefaultUuid = { - val actor1 = actorOf[Tester1] - val actor2 = actorOf[Tester1] + val actor1 = actorOf(Props[Tester1] + val actor2 = actorOf(Props[Tester1] val latch1 = (actor1 ? SetExpectedMessageCount(1)).as[CountDownLatch].get val latch2 = (actor2 ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:uuid:") @@ -209,7 +209,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldThrowExceptionWhenIdNotSet{ - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:id:") intercept[ActorIdentifierNotSetException] { @@ -219,7 +219,7 @@ class ActorProducerTest extends JUnitSuite with BeforeAndAfterAll { @Test def shouldThrowExceptionWhenUuidNotSet{ - val actor = actorOf[Tester1] + val actor = actorOf(Props[Tester1] val latch = (actor ? SetExpectedMessageCount(1)).as[CountDownLatch].get val endpoint = actorEndpoint("actor:uuid:") intercept[ActorIdentifierNotSetException] { diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/reflogic/ClusterActorRefCleanupMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/reflogic/ClusterActorRefCleanupMultiJvmSpec.scala index 87e2799da3..e723959c86 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/reflogic/ClusterActorRefCleanupMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/reflogic/ClusterActorRefCleanupMultiJvmSpec.scala @@ -37,7 +37,7 @@ class ClusterActorRefCleanupMultiJvmNode1 extends MasterClusterTestNode { Cluster.node.start() barrier("awaitStarted", NrOfNodes).await() - val ref = Actor.actorOf[ClusterActorRefCleanupMultiJvmSpec.TestActor]("service-test") + val ref = Actor.actorOf(Props[ClusterActorRefCleanupMultiJvmSpec.TestActor]("service-test") ref.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/nosnapshot/ReplicationTransactionLogWriteBehindNoSnapshotMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/nosnapshot/ReplicationTransactionLogWriteBehindNoSnapshotMultiJvmSpec.scala index b337007754..1d787c6572 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/nosnapshot/ReplicationTransactionLogWriteBehindNoSnapshotMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/nosnapshot/ReplicationTransactionLogWriteBehindNoSnapshotMultiJvmSpec.scala @@ -42,7 +42,7 @@ // } // barrier("create-actor-on-node1", NrOfNodes) { -// val actorRef = Actor.actorOf[HelloWorld]("hello-world-write-behind-nosnapshot") +// val actorRef = Actor.actorOf(Props[HelloWorld]("hello-world-write-behind-nosnapshot") // // node.isInUseOnNode("hello-world") must be(true) // actorRef.address must be("hello-world-write-behind-nosnapshot") // for (i ← 0 until 10) { diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/snapshot/ReplicationTransactionLogWriteBehindSnapshotMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/snapshot/ReplicationTransactionLogWriteBehindSnapshotMultiJvmSpec.scala index b60891300c..7f3a6fc683 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/snapshot/ReplicationTransactionLogWriteBehindSnapshotMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writebehind/snapshot/ReplicationTransactionLogWriteBehindSnapshotMultiJvmSpec.scala @@ -44,7 +44,7 @@ // } // barrier("create-actor-on-node1", NrOfNodes) { -// val actorRef = Actor.actorOf[HelloWorld]("hello-world-write-behind-snapshot") +// val actorRef = Actor.actorOf(Props[HelloWorld]("hello-world-write-behind-snapshot") // node.isInUseOnNode("hello-world-write-behind-snapshot") must be(true) // actorRef.address must be("hello-world-write-behind-snapshot") // var counter = 0 diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/nosnapshot/ReplicationTransactionLogWriteThroughNoSnapshotMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/nosnapshot/ReplicationTransactionLogWriteThroughNoSnapshotMultiJvmSpec.scala index fd2ff324da..2626d0fe8f 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/nosnapshot/ReplicationTransactionLogWriteThroughNoSnapshotMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/nosnapshot/ReplicationTransactionLogWriteThroughNoSnapshotMultiJvmSpec.scala @@ -44,7 +44,7 @@ // } // barrier("create-actor-on-node1", NrOfNodes) { -// val actorRef = Actor.actorOf[HelloWorld]("hello-world-write-through-nosnapshot") +// val actorRef = Actor.actorOf(Props[HelloWorld]("hello-world-write-through-nosnapshot") // actorRef.address must be("hello-world-write-through-nosnapshot") // for (i ← 0 until 10) // (actorRef ? Count(i)).as[String] must be(Some("World from node [node1]")) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/snapshot/ReplicationTransactionLogWriteThroughSnapshotMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/snapshot/ReplicationTransactionLogWriteThroughSnapshotMultiJvmSpec.scala index 583662ebe3..fe2231715e 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/snapshot/ReplicationTransactionLogWriteThroughSnapshotMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/replication/transactionlog/writethrough/snapshot/ReplicationTransactionLogWriteThroughSnapshotMultiJvmSpec.scala @@ -42,7 +42,7 @@ // } // barrier("create-actor-on-node1", NrOfNodes) { -// val actorRef = Actor.actorOf[HelloWorld]("hello-world-write-through-snapshot") +// val actorRef = Actor.actorOf(Props[HelloWorld]("hello-world-write-through-snapshot") // node.isInUseOnNode("hello-world-write-through-snapshot") must be(true) // actorRef.address must be("hello-world-write-through-snapshot") // var counter = 0 diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/failover/DirectRoutingFailoverMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/failover/DirectRoutingFailoverMultiJvmSpec.scala index 46463f6537..260a365019 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/failover/DirectRoutingFailoverMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/failover/DirectRoutingFailoverMultiJvmSpec.scala @@ -44,7 +44,7 @@ class DirectRoutingFailoverMultiJvmNode1 extends MasterClusterTestNode { } LocalCluster.barrier("actor-creation", NrOfNodes) { - actor = Actor.actorOf[SomeActor]("service-hello") + actor = Actor.actorOf(Props[SomeActor]("service-hello") } LocalCluster.barrier("verify-actor", NrOfNodes) { diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/homenode/HomeNode1MultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/homenode/HomeNode1MultiJvmSpec.scala index 2b84c0c3c9..6ce2219978 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/homenode/HomeNode1MultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/homenode/HomeNode1MultiJvmSpec.scala @@ -45,11 +45,11 @@ class HomeNodeMultiJvmNode2 extends ClusterTestNode { Cluster.node.start() barrier("waiting-for-begin", NrOfNodes).await() - val actorNode1 = Actor.actorOf[SomeActor]("service-node1") + val actorNode1 = Actor.actorOf(Props[SomeActor]("service-node1") val name1 = (actorNode1 ? "identify").get.asInstanceOf[String] name1 must equal("node1") - val actorNode2 = Actor.actorOf[SomeActor]("service-node2") + val actorNode2 = Actor.actorOf(Props[SomeActor]("service-node2") val name2 = (actorNode2 ? "identify").get.asInstanceOf[String] name2 must equal("node2") diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/normalusage/SingleReplicaDirectRoutingMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/normalusage/SingleReplicaDirectRoutingMultiJvmSpec.scala index e96804dfe2..a7b61af3e7 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/normalusage/SingleReplicaDirectRoutingMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/direct/normalusage/SingleReplicaDirectRoutingMultiJvmSpec.scala @@ -48,7 +48,7 @@ class SingleReplicaDirectRoutingMultiJvmNode2 extends ClusterTestNode { Cluster.node.start() LocalCluster.barrier("waiting-for-begin", NrOfNodes).await() - val actor = Actor.actorOf[SomeActor]("service-hello").asInstanceOf[ClusterActorRef] + val actor = Actor.actorOf(Props[SomeActor]("service-hello").asInstanceOf[ClusterActorRef] actor.isRunning must be(true) val result = (actor ? "identify").get diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/failover/RandomFailoverMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/failover/RandomFailoverMultiJvmSpec.scala index e13688f2dd..2842c55a97 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/failover/RandomFailoverMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/failover/RandomFailoverMultiJvmSpec.scala @@ -49,7 +49,7 @@ class RandomFailoverMultiJvmNode1 extends MasterClusterTestNode { } barrier("actor-creation", NrOfNodes) { - actor = Actor.actorOf[SomeActor]("service-hello") + actor = Actor.actorOf(Props[SomeActor]("service-hello") actor.isInstanceOf[ClusterActorRef] must be(true) } diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/homenode/HomeNodeMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/homenode/HomeNodeMultiJvmSpec.scala index f29e441864..a8f4887464 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/homenode/HomeNodeMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/homenode/HomeNodeMultiJvmSpec.scala @@ -45,11 +45,11 @@ class HomeNodeMultiJvmNode2 extends ClusterTestNode { Cluster.node.start() barrier("waiting-for-begin", NrOfNodes).await() - val actorNode1 = Actor.actorOf[SomeActor]("service-node1") + val actorNode1 = Actor.actorOf(Props[SomeActor]("service-node1") val nameNode1 = (actorNode1 ? "identify").get.asInstanceOf[String] nameNode1 must equal("node1") - val actorNode2 = Actor.actorOf[SomeActor]("service-node2") + val actorNode2 = Actor.actorOf(Props[SomeActor]("service-node2") val nameNode2 = (actorNode2 ? "identify").get.asInstanceOf[String] nameNode2 must equal("node2") diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_1/Random1ReplicaMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_1/Random1ReplicaMultiJvmSpec.scala index ddda4a07b7..c9e0412be2 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_1/Random1ReplicaMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_1/Random1ReplicaMultiJvmSpec.scala @@ -36,7 +36,7 @@ class Random1ReplicaMultiJvmNode1 extends MasterClusterTestNode { "create clustered actor, get a 'local' actor on 'home' node and a 'ref' to actor on remote node" in { Cluster.node.start() - var hello = Actor.actorOf[HelloWorld]("service-hello") + var hello = Actor.actorOf(Props[HelloWorld]("service-hello") hello must not equal (null) hello.address must equal("service-hello") hello.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_3/Random3ReplicasMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_3/Random3ReplicasMultiJvmSpec.scala index 41f54911e1..edb000b566 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_3/Random3ReplicasMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/random/replicationfactor_3/Random3ReplicasMultiJvmSpec.scala @@ -64,7 +64,7 @@ class Random3ReplicasMultiJvmNode2 extends ClusterTestNode { //check if the actorRef is the expected remoteActorRef. var hello: ActorRef = null - hello = Actor.actorOf[HelloWorld]("service-hello") + hello = Actor.actorOf(Props[HelloWorld]("service-hello") hello must not equal (null) hello.address must equal("service-hello") hello.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/failover/RoundRobinFailoverMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/failover/RoundRobinFailoverMultiJvmSpec.scala index 5b8791231d..63cd6c6313 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/failover/RoundRobinFailoverMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/failover/RoundRobinFailoverMultiJvmSpec.scala @@ -49,7 +49,7 @@ class RoundRobinFailoverMultiJvmNode1 extends MasterClusterTestNode { } barrier("actor-creation", NrOfNodes) { - actor = Actor.actorOf[SomeActor]("service-hello") + actor = Actor.actorOf(Props[SomeActor]("service-hello") actor.isInstanceOf[ClusterActorRef] must be(true) } diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/homenode/HomeNodeMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/homenode/HomeNodeMultiJvmSpec.scala index bb5499be58..4dc9e96429 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/homenode/HomeNodeMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/homenode/HomeNodeMultiJvmSpec.scala @@ -48,11 +48,11 @@ class HomeNodeMultiJvmNode2 extends ClusterTestNode { Cluster.node.start() barrier("waiting-for-begin", NrOfNodes).await() - val actorNode1 = Actor.actorOf[SomeActor]("service-node1") + val actorNode1 = Actor.actorOf(Props[SomeActor]("service-node1") val name1 = (actorNode1 ? "identify").get.asInstanceOf[String] name1 must equal("node1") - val actorNode2 = Actor.actorOf[SomeActor]("service-node2") + val actorNode2 = Actor.actorOf(Props[SomeActor]("service-node2") val name2 = (actorNode2 ? "identify").get.asInstanceOf[String] name2 must equal("node2") diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_1/RoundRobin1ReplicaMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_1/RoundRobin1ReplicaMultiJvmSpec.scala index c229d2c6c9..35938749ba 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_1/RoundRobin1ReplicaMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_1/RoundRobin1ReplicaMultiJvmSpec.scala @@ -35,7 +35,7 @@ class RoundRobin1ReplicaMultiJvmNode1 extends MasterClusterTestNode { "create clustered actor, get a 'local' actor on 'home' node and a 'ref' to actor on remote node" in { Cluster.node.start() - var hello = Actor.actorOf[HelloWorld]("service-hello") + var hello = Actor.actorOf(Props[HelloWorld]("service-hello") hello must not equal (null) hello.address must equal("service-hello") hello.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_2/RoundRobin2ReplicasMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_2/RoundRobin2ReplicasMultiJvmSpec.scala index 63a1f04ce7..a99dbbbae9 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_2/RoundRobin2ReplicasMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_2/RoundRobin2ReplicasMultiJvmSpec.scala @@ -89,7 +89,7 @@ class RoundRobin2ReplicasMultiJvmNode2 extends ClusterTestNode { //check if the actorRef is the expected remoteActorRef. var hello: ActorRef = null barrier("get-ref-to-actor-on-node2", NrOfNodes) { - hello = Actor.actorOf[HelloWorld]("service-hello") + hello = Actor.actorOf(Props[HelloWorld]("service-hello") hello must not equal (null) hello.address must equal("service-hello") hello.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_3/RoundRobin3ReplicasMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_3/RoundRobin3ReplicasMultiJvmSpec.scala index 93bfbf4c47..ead1d693c0 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_3/RoundRobin3ReplicasMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/roundrobin/replicationfactor_3/RoundRobin3ReplicasMultiJvmSpec.scala @@ -91,7 +91,7 @@ // //check if the actorRef is the expected remoteActorRef. // var hello: ActorRef = null // barrier("get-ref-to-actor-on-node2", NrOfNodes) { -// hello = Actor.actorOf[HelloWorld]("service-hello") +// hello = Actor.actorOf(Props[HelloWorld]("service-hello") // hello must not equal (null) // hello.address must equal("service-hello") // hello.isInstanceOf[ClusterActorRef] must be(true) diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/scattergather/failover/ScatterGatherFailoverMultiJvmSpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/scattergather/failover/ScatterGatherFailoverMultiJvmSpec.scala index b19571f5a4..90f9e0aa56 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/scattergather/failover/ScatterGatherFailoverMultiJvmSpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/routing/scattergather/failover/ScatterGatherFailoverMultiJvmSpec.scala @@ -63,7 +63,7 @@ class ScatterGatherFailoverMultiJvmNode1 extends MasterClusterTestNode { /* FIXME: Uncomment, when custom routers will be fully supported (ticket #1109) - val actor = Actor.actorOf[TestActor]("service-hello").asInstanceOf[ClusterActorRef] + val actor = Actor.actorOf(Props[TestActor]("service-hello").asInstanceOf[ClusterActorRef] identifyConnections(actor).size() must be(2) diff --git a/akka-docs/disabled/camel.rst b/akka-docs/disabled/camel.rst index 8b2b84c992..fd9d6c1181 100644 --- a/akka-docs/disabled/camel.rst +++ b/akka-docs/disabled/camel.rst @@ -5,9 +5,7 @@ Camel ####### -For an introduction to akka-camel, see also the `Appendix E - Akka and Camel`_ -(pdf) of the book `Camel in Action`_. - +======= .. _Appendix E - Akka and Camel: http://www.manning.com/ibsen/appEsample.pdf .. _Camel in Action: http://www.manning.com/ibsen/ @@ -62,7 +60,7 @@ one-liner. Here's an example. } // start and expose actor via tcp - val myActor = actorOf[MyActor] + val myActor = actorOf(Props[MyActor]) The above example exposes an actor over a tcp endpoint on port 6200 via Apache Camel's `Mina component`_. The actor implements the endpointUri method to define @@ -362,7 +360,7 @@ after the ActorRef method returned. import akka.actor.Actor._ - val actor = actorOf[Consumer1] // create Consumer actor and activate endpoint in background + val actor = actorOf(Props[Consumer1]) // create Consumer actor and activate endpoint in background **Java** @@ -371,7 +369,7 @@ after the ActorRef method returned. import static akka.actor.Actors.*; import akka.actor.ActorRef; - ActorRef actor = actorOf(Consumer1.class); // create Consumer actor and activate endpoint in background + ActorRef actor = actorOf(new Props(Consumer1.class)); // create Consumer actor and activate endpoint in background Typed actors @@ -544,7 +542,7 @@ still in progress after the ``ActorRef.stop`` method returned. import akka.actor.Actor._ - val actor = actorOf[Consumer1] // create Consumer actor + val actor = actorOf(Props[Consumer1]) // create Consumer actor actor // activate endpoint in background // ... actor.stop // deactivate endpoint in background @@ -556,7 +554,7 @@ still in progress after the ``ActorRef.stop`` method returned. import static akka.actor.Actors.*; import akka.actor.ActorRef; - ActorRef actor = actorOf(Consumer1.class); // create Consumer actor and activate endpoint in background + ActorRef actor = actorOf(new Props(Consumer1.class)); // create Consumer actor and activate endpoint in background // ... actor.stop(); // deactivate endpoint in background @@ -872,7 +870,7 @@ actor and register it at the remote server. // ... startCamelService - val consumer = val consumer = actorOf[RemoteActor1] + val consumer = val consumer = actorOf(Props[RemoteActor1]) remote.start("localhost", 7777) remote.register(consumer) // register and start remote consumer @@ -888,7 +886,7 @@ actor and register it at the remote server. // ... CamelServiceManager.startCamelService(); - ActorRef actor = actorOf(RemoteActor1.class); + ActorRef actor = actorOf(new Props(RemoteActor1.class)); remote().start("localhost", 7777); remote().register(actor); // register and start remote consumer @@ -1028,7 +1026,7 @@ used. import akka.actor.Actor._ import akka.actor.ActorRef - val producer = actorOf[Producer1] + val producer = actorOf(Props[Producer1]) val response = (producer ? "akka rocks").get val body = response.bodyAs[String] @@ -1040,7 +1038,7 @@ used. import static akka.actor.Actors.*; import akka.camel.Message; - ActorRef producer = actorOf(Producer1.class); + ActorRef producer = actorOf(new Props(Producer1.class)); Message response = (Message)producer.sendRequestReply("akka rocks"); String body = response.getBodyAs(String.class) @@ -1156,7 +1154,7 @@ argument. import akka.actor.ActorRef; ActorRef target = ... - ActorRef producer = actorOf(new Producer1Factory(target)); + ActorRef producer = actorOf(Props(new Producer1Factory(target))); producer; Before producing messages to endpoints, producer actors can pre-process them by @@ -1946,7 +1944,7 @@ ends at the target actor. import akka.camel.{Message, CamelContextManager, CamelServiceManager} object CustomRouteExample extends Application { - val target = actorOf[CustomRouteTarget] + val target = actorOf(Props[CustomRouteTarget]) CamelServiceManager.startCamelService CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder(target.uuid)) @@ -1982,7 +1980,7 @@ ends at the target actor. public class CustomRouteExample { public static void main(String... args) throws Exception { - ActorRef target = actorOf(CustomRouteTarget.class); + ActorRef target = actorOf(new Props(CustomRouteTarget.class)); CamelServiceManager.startCamelService(); CamelContextManager.getMandatoryContext().addRoutes(new CustomRouteBuilder(target.getUuid())); } @@ -2545,9 +2543,9 @@ as shown in the following snippet (see also `sample.camel.Boot`_). } // Wire and start the example actors - val httpTransformer = actorOf(new HttpTransformer) - val httpProducer = actorOf(new HttpProducer(httpTransformer)) - val httpConsumer = actorOf(new HttpConsumer(httpProducer)) + val httpTransformer = actorOf(Props(new HttpTransformer)) + val httpProducer = actorOf(Props(new HttpProducer(httpTransformer))) + val httpConsumer = actorOf(Props(new HttpConsumer(httpProducer))) The `jetty endpoints`_ of HttpConsumer and HttpProducer support asynchronous in-out message exchanges and do not allocate threads for the full duration of @@ -2637,9 +2635,9 @@ follows. CamelContextManager.init() CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) - val producer = actorOf[Producer1] - val mediator = actorOf(new Transformer(producer)) - val consumer = actorOf(new Consumer3(mediator)) + val producer = actorOf(Props[Producer1]) + val mediator = actorOf(Props(new Transformer(producer))) + val consumer = actorOf(Props(new Consumer3(mediator))) } class CustomRouteBuilder extends RouteBuilder { @@ -2741,11 +2739,11 @@ Wiring these actors to implement the above example is as simple as // Setup publish/subscribe example val jmsUri = "jms:topic:test" - val jmsSubscriber1 = actorOf(new Subscriber("jms-subscriber-1", jmsUri)) - val jmsSubscriber2 = actorOf(new Subscriber("jms-subscriber-2", jmsUri)) - val jmsPublisher = actorOf(new Publisher("jms-publisher", jmsUri)) + val jmsSubscriber1 = actorOf(Props(new Subscriber("jms-subscriber-1", jmsUri))) + val jmsSubscriber2 = actorOf(Props(new Subscriber("jms-subscriber-2", jmsUri))) + val jmsPublisher = actorOf(Props(new Publisher("jms-publisher", jmsUri))) - val jmsPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher)) + val jmsPublisherBridge = actorOf(Props(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher))) } To publish messages to subscribers one could of course also use the JMS API @@ -2838,10 +2836,10 @@ to be changed. // Setup publish/subscribe example val cometdUri = "cometd://localhost:8111/test/abc?resourceBase=target" - val cometdSubscriber = actorOf(new Subscriber("cometd-subscriber", cometdUri)) - val cometdPublisher = actorOf(new Publisher("cometd-publisher", cometdUri)) + val cometdSubscriber = actorOf(Props(new Subscriber("cometd-subscriber", cometdUri))) + val cometdPublisher = actorOf(Props(new Publisher("cometd-publisher", cometdUri))) - val cometdPublisherBridge = actorOf(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher)) + val cometdPublisherBridge = actorOf(Props(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher))) } @@ -2884,7 +2882,7 @@ seconds: startCamelService // create and start a quartz actor - val myActor = actorOf[MyQuartzActor] + val myActor = actorOf(Props[MyQuartzActor]) } // end main diff --git a/akka-docs/disabled/clustering.rst b/akka-docs/disabled/clustering.rst index 559233143d..017994cb8a 100644 --- a/akka-docs/disabled/clustering.rst +++ b/akka-docs/disabled/clustering.rst @@ -48,7 +48,7 @@ cluster node. Cluster configuration ~~~~~~~~~~~~~~~~~~~~~ -Cluster is configured in the ``akka.cloud.cluster`` section in the :ref:`configuration`. +Cluster is configured in the ``akka.cloud.cluster`` section in the :ref:`configuration`. Here you specify the default addresses to the ZooKeeper servers, timeouts, if compression should be on or off, and so on. @@ -328,7 +328,7 @@ created actor:: val clusterNode = Cluster.newNode(NodeAddress("test-cluster", "node1")).start - val hello = actorOf[HelloActor].start.asInstanceOf[LocalActorRef] + val hello = actorOf(Props[HelloActor]).asInstanceOf[LocalActorRef] val serializeMailbox = false val nrOfInstances = 5 diff --git a/akka-docs/disabled/examples/Pi.scala b/akka-docs/disabled/examples/Pi.scala index 2b0fb45914..9fcddef1a0 100644 --- a/akka-docs/disabled/examples/Pi.scala +++ b/akka-docs/disabled/examples/Pi.scala @@ -62,7 +62,7 @@ object Pi extends App { //#create-workers // create the workers - val workers = Vector.fill(nrOfWorkers)(actorOf[Worker]) + val workers = Vector.fill(nrOfWorkers)(actorOf(Props[Worker]) // wrap them with a load-balancing router val router = Routing.actorOf(RoutedProps().withRoundRobinRouter.withLocalConnections(workers), "pi") @@ -117,8 +117,7 @@ object Pi extends App { val latch = new CountDownLatch(1) // create the master - val master = actorOf( - new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) + val master = actorOf(Props(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch))) // start the calculation master ! Calculate diff --git a/akka-docs/intro/code/tutorials/first/Pi.scala b/akka-docs/intro/code/tutorials/first/Pi.scala index 6be88d0f32..4c82dfaa93 100644 --- a/akka-docs/intro/code/tutorials/first/Pi.scala +++ b/akka-docs/intro/code/tutorials/first/Pi.scala @@ -66,7 +66,7 @@ // //#create-workers // // create the workers -// val workers = Vector.fill(nrOfWorkers)(system.actorOf[Worker]) +// val workers = Vector.fill(nrOfWorkers)(system.actorOf(Props[Worker]) // // wrap them with a load-balancing router // val router = system.actorOf(RoutedProps().withRoundRobinRouter.withLocalConnections(workers), "pi") @@ -119,7 +119,7 @@ // val latch = new CountDownLatch(1) // // create the master -// val master = system.actorOf(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) +// val master = system.actorOf(Props(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) // // start the calculation // master ! Calculate diff --git a/akka-docs/intro/getting-started-first-java.rst b/akka-docs/intro/getting-started-first-java.rst index bf694e5fe2..6d429b160d 100644 --- a/akka-docs/intro/getting-started-first-java.rst +++ b/akka-docs/intro/getting-started-first-java.rst @@ -158,8 +158,8 @@ Here is the layout that Maven created:: As you can see we already have a Java source file called ``App.java``, let's now rename it to ``Pi.java``. -We also need to edit the ``pom.xml`` build file. Let's add the dependency we need as well as the Maven repository it should download it from. The Akka Maven repository can be found at ``_ -and Typesafe provides ``_ that proxies several other repositories, including akka.io. +We also need to edit the ``pom.xml`` build file. Let's add the dependency we need as well as the Maven repository it should download it from. The Akka Maven repository can be found at ``_ +and Typesafe provides ``_ that proxies several other repositories, including akka.io. It should now look something like this: .. code-block:: xml @@ -221,6 +221,7 @@ We start by creating a ``Pi.java`` file and adding these import statements at th import static akka.actor.Actors.poisonPill; import static java.util.Arrays.asList; + import akka.actor.Props; import akka.actor.ActorRef; import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; @@ -337,15 +338,15 @@ The master actor is a little bit more involved. In its constructor we need to cr // create the workers final ActorRef[] workers = new ActorRef[nrOfWorkers]; for (int i = 0; i < nrOfWorkers; i++) { - workers[i] = actorOf(Worker.class); + workers[i] = actorOf(new Props(Worker.class)); } // wrap them with a load-balancing router - ActorRef router = actorOf(new UntypedActorFactory() { + ActorRef router = actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new PiRouter(workers); } - }); + })); } } @@ -359,7 +360,7 @@ One thing to note is that we used two different versions of the ``actorOf`` meth The actor's life-cycle is: -- Created & Started -- ``Actor.actorOf[MyActor]`` -- can receive messages +- Created & Started -- ``Actor.actorOf(Props[MyActor]`` -- can receive messages - Stopped -- ``actorRef.stop()`` -- can **not** receive messages Once the actor has been stopped it is dead and can not be started again. @@ -404,15 +405,15 @@ Here is the master actor:: // create the workers final ActorRef[] workers = new ActorRef[nrOfWorkers]; for (int i = 0; i < nrOfWorkers; i++) { - workers[i] = actorOf(Worker.class); + workers[i] = actorOf(new Props(Worker.class)); } // wrap them with a load-balancing router - router = actorOf(new UntypedActorFactory() { + router = actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new PiRouter(workers); } - }); + })); } // message handler @@ -495,11 +496,11 @@ Now the only thing that is left to implement is the runner that should bootstrap final CountDownLatch latch = new CountDownLatch(1); // create the master - ActorRef master = actorOf(new UntypedActorFactory() { + ActorRef master = actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch); } - }); + })); // start the calculation master.tell(new Calculate()); @@ -519,6 +520,7 @@ Before we package it up and run it, let's take a look at the full code now, with import static akka.actor.Actors.poisonPill; import static java.util.Arrays.asList; + import akka.actor.Props; import akka.actor.ActorRef; import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; @@ -629,15 +631,15 @@ Before we package it up and run it, let's take a look at the full code now, with // create the workers final ActorRef[] workers = new ActorRef[nrOfWorkers]; for (int i = 0; i < nrOfWorkers; i++) { - workers[i] = actorOf(Worker.class); + workers[i] = actorOf(new Props(Worker.class)); } // wrap them with a load-balancing router - router = actorOf(new UntypedActorFactory() { + router = actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new PiRouter(workers); } - }); + })); } // message handler @@ -691,11 +693,11 @@ Before we package it up and run it, let's take a look at the full code now, with final CountDownLatch latch = new CountDownLatch(1); // create the master - ActorRef master = actorOf(new UntypedActorFactory() { + ActorRef master = actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch); } - }); + })); // start the calculation master.tell(new Calculate()); diff --git a/akka-docs/intro/getting-started-first-scala-eclipse.rst b/akka-docs/intro/getting-started-first-scala-eclipse.rst index 487d8b4509..da473990d1 100644 --- a/akka-docs/intro/getting-started-first-scala-eclipse.rst +++ b/akka-docs/intro/getting-started-first-scala-eclipse.rst @@ -157,7 +157,7 @@ If you have not already done so, now is the time to create an Eclipse project fo Using SBT in Eclipse ^^^^^^^^^^^^^^^^^^^^ -If you are an `SBT `_ user, you can follow the :ref:`getting-started-first-scala-download-sbt` instruction and additionally install the ``sbteclipse`` plugin. This adds support for generating Eclipse project files from your SBT project. +If you are an `SBT `_ user, you can follow the :ref:`getting-started-first-scala-download-sbt` instruction and additionally install the ``sbteclipse`` plugin. This adds support for generating Eclipse project files from your SBT project. You need to install the plugin as described in the `README of sbteclipse `_ Then run the ``eclipse`` target to generate the Eclipse project:: @@ -253,7 +253,7 @@ Now create a new class for the master actor. The master actor is a little bit mo and then we can create the workers:: // create the workers - val workers = Vector.fill(nrOfWorkers)(actorOf[Worker]) + val workers = Vector.fill(nrOfWorkers)(actorOf(Props[Worker]) // wrap them with a load-balancing router val router = Routing.loadBalancerActor(CyclicIterator(workers)) @@ -262,11 +262,11 @@ As you can see we are using the ``actorOf`` factory method to create actors, thi import akka.actor.Actor.actorOf -There are two versions of ``actorOf``; one of them taking a actor type and the other one an instance of an actor. The former one (``actorOf[MyActor]``) is used when the actor class has a no-argument constructor while the second one (``actorOf(new MyActor(..))``) is used when the actor class has a constructor that takes arguments. This is the only way to create an instance of an Actor and the ``actorOf`` method ensures this. The latter version is using call-by-name and lazily creates the actor within the scope of the ``actorOf`` method. The ``actorOf`` method instantiates the actor and returns, not an instance to the actor, but an instance to an ``ActorRef``. This reference is the handle through which you communicate with the actor. It is immutable, serializable and location-aware meaning that it "remembers" its original actor even if it is sent to other nodes across the network and can be seen as the equivalent to the Erlang actor's PID. +There are two versions of ``actorOf``; one of them taking a actor type and the other one an instance of an actor. The former one (``actorOf(Props[MyActor]``) is used when the actor class has a no-argument constructor while the second one (``actorOf(Props(new MyActor(..))``) is used when the actor class has a constructor that takes arguments. This is the only way to create an instance of an Actor and the ``actorOf`` method ensures this. The latter version is using call-by-name and lazily creates the actor within the scope of the ``actorOf`` method. The ``actorOf`` method instantiates the actor and returns, not an instance to the actor, but an instance to an ``ActorRef``. This reference is the handle through which you communicate with the actor. It is immutable, serializable and location-aware meaning that it "remembers" its original actor even if it is sent to other nodes across the network and can be seen as the equivalent to the Erlang actor's PID. The actor's life-cycle is: -- Created -- ``Actor.actorOf[MyActor]`` -- can **not** receive messages +- Created -- ``Actor.actorOf(Props[MyActor]`` -- can **not** receive messages - Started -- ``actorRef`` -- can receive messages - Stopped -- ``actorRef.stop()`` -- can **not** receive messages @@ -289,7 +289,7 @@ Here is the master actor:: var start: Long = _ // create the workers - val workers = Vector.fill(nrOfWorkers)(actorOf[Worker]) + val workers = Vector.fill(nrOfWorkers)(actorOf(Props[Worker]) // wrap them with a load-balancing router val router = Routing.loadBalancerActor(CyclicIterator(workers)) @@ -364,8 +364,7 @@ The ``Pi`` object is a perfect container module for our actors and messages, so val latch = new CountDownLatch(1) // create the master - val master = actorOf( - new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)) + val master = actorOf(Props(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch))) // start the calculation master ! Calculate diff --git a/akka-docs/intro/getting-started-first-scala.rst b/akka-docs/intro/getting-started-first-scala.rst index 6a8720f843..35ac80bcd5 100644 --- a/akka-docs/intro/getting-started-first-scala.rst +++ b/akka-docs/intro/getting-started-first-scala.rst @@ -303,9 +303,9 @@ imported:: import akka.actor.Actor.actorOf There are two versions of ``actorOf``; one of them taking a actor type and the -other one an instance of an actor. The former one (``actorOf[MyActor]``) is used +other one an instance of an actor. The former one (``actorOf(Props[MyActor]``) is used when the actor class has a no-argument constructor while the second one -(``actorOf(new MyActor(..))``) is used when the actor class has a constructor +(``actorOf(Props(new MyActor(..))``) is used when the actor class has a constructor that takes arguments. This is the only way to create an instance of an Actor and the ``actorOf`` method ensures this. The latter version is using call-by-name and lazily creates the actor within the scope of the ``actorOf`` method. The @@ -318,7 +318,7 @@ Erlang actor's PID. The actor's life-cycle is: -- Created & Started -- ``Actor.actorOf[MyActor]`` -- can receive messages +- Created & Started -- ``Actor.actorOf(Props[MyActor])`` -- can receive messages - Stopped -- ``actorRef.stop()`` -- can **not** receive messages Once the actor has been stopped it is dead and can not be started again. diff --git a/akka-docs/java/code/akka/docs/actor/FirstUntypedActor.java b/akka-docs/java/code/akka/docs/actor/FirstUntypedActor.java index 42b94df39c..d09452f7db 100644 --- a/akka-docs/java/code/akka/docs/actor/FirstUntypedActor.java +++ b/akka-docs/java/code/akka/docs/actor/FirstUntypedActor.java @@ -1,12 +1,13 @@ package akka.docs.actor; import akka.actor.ActorRef; +import akka.actor.Props; import static akka.actor.Actors.*; import akka.actor.UntypedActor; //#context-actorOf public class FirstUntypedActor extends UntypedActor { - ActorRef myActor = getContext().actorOf(MyActor.class); + ActorRef myActor = getContext().actorOf(new Props(MyActor.class)); //#context-actorOf diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorSwapper.java b/akka-docs/java/code/akka/docs/actor/UntypedActorSwapper.java index 7ec924da57..cf9e3bfbf7 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorSwapper.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorSwapper.java @@ -2,6 +2,7 @@ package akka.docs.actor; import static akka.docs.actor.UntypedActorSwapper.Swap.SWAP; import akka.actor.ActorRef; +import akka.actor.Props; import akka.actor.ActorSystem; import akka.actor.UnhandledMessageException; import akka.actor.UntypedActor; @@ -40,7 +41,7 @@ public class UntypedActorSwapper { public static void main(String... args) { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef swap = system.actorOf(Swapper.class); + ActorRef swap = system.actorOf(new Props(Swapper.class)); swap.tell(SWAP); // logs Hi swap.tell(SWAP); // logs Ho swap.tell(SWAP); // logs Hi @@ -50,4 +51,4 @@ public class UntypedActorSwapper { } } -//#swapper \ No newline at end of file +//#swapper diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java index 756618eef5..eefaeda1e6 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorTestBase.java @@ -3,6 +3,7 @@ package akka.docs.actor; //#imports import akka.actor.ActorRef; import akka.actor.ActorSystem; +import akka.actor.Props; //#imports @@ -38,7 +39,7 @@ public class UntypedActorTestBase { public void systemActorOf() { //#system-actorOf ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(MyUntypedActor.class); + ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class)); //#system-actorOf myActor.tell("test"); system.stop(); @@ -48,7 +49,7 @@ public class UntypedActorTestBase { public void contextActorOf() { //#context-actorOf ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(MyUntypedActor.class); + ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class)); //#context-actorOf myActor.tell("test"); system.stop(); @@ -59,11 +60,11 @@ public class UntypedActorTestBase { ActorSystem system = ActorSystem.create("MySystem"); //#creating-constructor // allows passing in arguments to the MyActor constructor - ActorRef myActor = system.actorOf(new UntypedActorFactory() { + ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new MyActor("..."); } - }); + })); //#creating-constructor myActor.tell("test"); system.stop(); @@ -74,8 +75,7 @@ public class UntypedActorTestBase { ActorSystem system = ActorSystem.create("MySystem"); //#creating-props MessageDispatcher dispatcher = system.dispatcherFactory().newFromConfig("my-dispatcher"); - ActorRef myActor = system.actorOf(new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), - "myactor"); + ActorRef myActor = system.actorOf(new Props().withCreator(MyUntypedActor.class).withDispatcher(dispatcher), "myactor"); //#creating-props myActor.tell("test"); system.stop(); @@ -84,11 +84,11 @@ public class UntypedActorTestBase { @Test public void usingAsk() { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(new UntypedActorFactory() { + ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new MyAskActor(); } - }); + })); //#using-ask Future future = myActor.ask("Hello", 1000); @@ -109,7 +109,7 @@ public class UntypedActorTestBase { @Test public void receiveTimeout() { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(MyReceivedTimeoutUntypedActor.class); + ActorRef myActor = system.actorOf(new Props(MyReceivedTimeoutUntypedActor.class)); myActor.tell("Hello"); system.stop(); } @@ -117,7 +117,7 @@ public class UntypedActorTestBase { @Test public void usePoisonPill() { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(MyUntypedActor.class); + ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class)); //#poison-pill myActor.tell(poisonPill()); //#poison-pill @@ -127,7 +127,7 @@ public class UntypedActorTestBase { @Test public void useKill() { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef victim = system.actorOf(MyUntypedActor.class); + ActorRef victim = system.actorOf(new Props(MyUntypedActor.class)); //#kill victim.tell(kill()); //#kill @@ -137,11 +137,11 @@ public class UntypedActorTestBase { @Test public void useBecome() { ActorSystem system = ActorSystem.create("MySystem"); - ActorRef myActor = system.actorOf(new UntypedActorFactory() { + ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() { public UntypedActor create() { return new HotSwapActor(); } - }); + })); myActor.tell("foo"); myActor.tell("bar"); myActor.tell("bar"); diff --git a/akka-docs/java/dispatchers.rst b/akka-docs/java/dispatchers.rst index b9c5a9fa41..2b5b311fef 100644 --- a/akka-docs/java/dispatchers.rst +++ b/akka-docs/java/dispatchers.rst @@ -6,7 +6,7 @@ Dispatchers (Java) .. sidebar:: Contents .. contents:: :local: - + The Dispatcher is an important piece that allows you to configure the right semantics and parameters for optimal performance, throughput and scalability. Different Actors have different needs. Akka supports dispatchers for both event-driven lightweight threads, allowing creation of millions threads on a single workstation, and thread-based Actors, where each dispatcher is bound to a dedicated OS thread. @@ -127,7 +127,7 @@ should have, as shown above. This defines the number of messages for a specific Actor the dispatcher should process in one single sweep; in other words, the dispatcher will bunch up to ``throughput`` message invocations together when having elected an actor to run. Setting this to a higher number will increase -throughput but lower fairness, and vice versa. If you don't specify it explicitly +throughput but lower fairness, and vice versa. If you don't specify it explicitly then it uses the value (5) defined for ``default-dispatcher`` in the :ref:`configuration`. Browse the :ref:`scaladoc` or look at the code for all the options available. @@ -143,10 +143,10 @@ Creating a Dispatcher with a priority mailbox using PriorityGenerator: .. code-block:: java package some.pkg; - + import akka.actor.*; import akka.dispatch.*; - + public class Main { // A simple Actor that just prints the messages it processes public static class MyActor extends UntypedActor { @@ -165,7 +165,7 @@ Creating a Dispatcher with a priority mailbox using PriorityGenerator: } public static void main(String[] args) { - // Create a new PriorityGenerator, lower prio means more important + // Create a new PriorityGenerator, lower prio means more important PriorityGenerator gen = new PriorityGenerator() { public int gen(Object message) { if (message.equals("highpriority")) return 0; // "highpriority" messages should be treated first if possible @@ -175,7 +175,7 @@ Creating a Dispatcher with a priority mailbox using PriorityGenerator: }; // We create an instance of the actor that will print out the messages it processes // We create a new Priority dispatcher and seed it with the priority generator - ActorRef ref = Actors.actorOf((new Props()).withCreator(MyActor.class).withDispatcher(new Dispatcher("foo", 5, new UnboundedPriorityMailbox(gen)))); + ActorRef ref = Actors.actorOf(new Props(MyActor.class).withDispatcher(new Dispatcher("foo", 5, new UnboundedPriorityMailbox(gen)))); } } diff --git a/akka-docs/java/routing.rst b/akka-docs/java/routing.rst index cb74f2ee01..5342ed882f 100644 --- a/akka-docs/java/routing.rst +++ b/akka-docs/java/routing.rst @@ -27,8 +27,8 @@ An UntypedDispatcher is an actor that routes incoming messages to outbound actor } public class MyRouter extends UntypedRouter { - private ActorRef pinger = actorOf(Pinger.class); - private ActorRef ponger = actorOf(Ponger.class); + private ActorRef pinger = actorOf(new Props(Pinger.class)); + private ActorRef ponger = actorOf(new Props(Ponger.class)); //Route Ping-messages to the pinger, and Pong-messages to the ponger public ActorRef route(Object message) { @@ -38,7 +38,7 @@ An UntypedDispatcher is an actor that routes incoming messages to outbound actor } } - ActorRef router = actorOf(MyRouter.class); + ActorRef router = actorOf(new Props(MyRouter.class)); router.tell("Ping"); //Prints "Pinger: Ping" router.tell("Pong"); //Prints "Ponger: Pong" @@ -71,8 +71,8 @@ An UntypedLoadBalancer is an actor that forwards messages it receives to a bound //Our load balancer, sends messages to a pinger, then a ponger, rinse and repeat. public class MyLoadBalancer extends UntypedLoadBalancer { private InfiniteIterator actors = new CyclicIterator(asList( - actorOf(Pinger.class), - actorOf(Ponger.class) + actorOf(new Props(Pinger.class)), + actorOf(new Props(Ponger.class)) )); public InfiniteIterator seq() { @@ -80,7 +80,7 @@ An UntypedLoadBalancer is an actor that forwards messages it receives to a bound } } - ActorRef balancer = actorOf(MyLoadBalancer.class); + ActorRef balancer = actorOf(new Props(MyLoadBalancer.class)); balancer.tell("Pong"); //Prints "Pinger: Pong" balancer.tell("Ping"); //Prints "Ponger: Ping" balancer.tell("Ping"); //Prints "Pinger: Ping" diff --git a/akka-docs/java/stm.rst b/akka-docs/java/stm.rst deleted file mode 100644 index 453cc580d9..0000000000 --- a/akka-docs/java/stm.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _stm-java: - -Software Transactional Memory (Java) -==================================== - -Documentation of Akka STM has not been migrated to Akka 2.0-SNAPSHOT yet. \ No newline at end of file diff --git a/akka-docs/java/transactors.rst b/akka-docs/java/transactors.rst deleted file mode 100644 index 27a006701e..0000000000 --- a/akka-docs/java/transactors.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _transactors-java: - -Transactors (Java) -================== - -Documentation of Akka Transactors has not been migrated to Akka 2.0-SNAPSHOT yet. \ No newline at end of file diff --git a/akka-docs/java/typed-actors.rst b/akka-docs/java/typed-actors.rst index b2e9615dec..f92828976a 100644 --- a/akka-docs/java/typed-actors.rst +++ b/akka-docs/java/typed-actors.rst @@ -4,7 +4,9 @@ Typed Actors (Java) .. sidebar:: Contents .. contents:: :local: - + +Module stability: **SOLID** + The Typed Actors are implemented through `Typed Actors `_. It uses AOP through `AspectWerkz `_ to turn regular POJOs into asynchronous non-blocking Actors with semantics of the Actor Model. Each method dispatch is turned into a message that is put on a queue to be processed by the Typed Actor sequentially one by one. If you are using the `Spring Framework `_ then take a look at Akka's `Spring integration `_. @@ -34,7 +36,7 @@ If you have a POJO with an interface implementation separation like this: .. code-block:: java import akka.actor.TypedActor; - + public class RegistrationServiceImpl extends TypedActor implements RegistrationService { public void register(User user, Credentials cred) { ... // register user @@ -135,7 +137,7 @@ Here is an example: } } - MathTypedActor math = TypedActor.actorOf(MathTypedActor .class, MathTypedActorImpl.class); + MathTypedActor math = TypedActor.typedActorOf(MathTypedActor.class, MathTypedActorImpl.class); // This method will return immediately when called, caller should wait on the Future for the result Future future = math.square(10); diff --git a/akka-docs/modules/camel.rst b/akka-docs/modules/camel.rst index ecdd956724..4aa988d609 100644 --- a/akka-docs/modules/camel.rst +++ b/akka-docs/modules/camel.rst @@ -5,5 +5,2899 @@ Camel ####### -The Akka Camel module has not been migrated to Akka 2.0-SNAPSHOT yet. +For an introduction to akka-camel, see also the `Appendix E - Akka and Camel`_ +(pdf) of the book `Camel in Action`_. +.. _Appendix E - Akka and Camel: http://www.manning.com/ibsen/appEsample.pdf +.. _Camel in Action: http://www.manning.com/ibsen/ + +Contents: + +.. contents:: :local: + +Other, more advanced external articles are: + +* `Akka Consumer Actors: New Features and Best Practices `_ +* `Akka Producer Actors: New Features and Best Practices `_ + + +Introduction +============ + +The akka-camel module allows actors, untyped actors, and typed actors to receive +and send messages over a great variety of protocols and APIs. This section gives +a brief overview of the general ideas behind the akka-camel module, the +remaining sections go into the details. In addition to the native Scala and Java +actor API, actors can now exchange messages with other systems over large number +of protocols and APIs such as HTTP, SOAP, TCP, FTP, SMTP or JMS, to mention a +few. At the moment, approximately 80 protocols and APIs are supported. + +The akka-camel module is based on `Apache Camel`_, a powerful and leight-weight +integration framework for the JVM. For an introduction to Apache Camel you may +want to read this `Apache Camel article`_. Camel comes with a +large number of `components`_ that provide bindings to different protocols and +APIs. The `camel-extra`_ project provides further components. + +.. _Apache Camel: http://camel.apache.org/ +.. _Apache Camel article: http://architects.dzone.com/articles/apache-camel-integration +.. _components: http://camel.apache.org/components.html +.. _camel-extra: http://code.google.com/p/camel-extra/ + +Usage of Camel's integration components in Akka is essentially a +one-liner. Here's an example. + +.. code-block:: scala + + import akka.actor.Actor + import akka.actor.Actor._ + import akka.camel.{Message, Consumer} + + class MyActor extends Actor with Consumer { + def endpointUri = "mina:tcp://localhost:6200?textline=true" + + def receive = { + case msg: Message => { /* ... */} + case _ => { /* ... */} + } + } + + // start and expose actor via tcp + val myActor = actorOf(Props[MyActor]) + +The above example exposes an actor over a tcp endpoint on port 6200 via Apache +Camel's `Mina component`_. The actor implements the endpointUri method to define +an endpoint from which it can receive messages. After starting the actor, tcp +clients can immediately send messages to and receive responses from that +actor. If the message exchange should go over HTTP (via Camel's `Jetty +component`_), only the actor's endpointUri method must be changed. + +.. _Mina component: http://camel.apache.org/mina.html +.. _Jetty component: http://camel.apache.org/jetty.html + +.. code-block:: scala + + class MyActor extends Actor with Consumer { + def endpointUri = "jetty:http://localhost:8877/example" + + def receive = { + case msg: Message => { /* ... */} + case _ => { /* ... */} + } + } + +Actors can also trigger message exchanges with external systems i.e. produce to +Camel endpoints. + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.{Producer, Oneway} + + class MyActor extends Actor with Producer with Oneway { + def endpointUri = "jms:queue:example" + } + +In the above example, any message sent to this actor will be added (produced) to +the example JMS queue. Producer actors may choose from the same set of Camel +components as Consumer actors do. + +The number of Camel components is constantly increasing. The akka-camel module +can support these in a plug-and-play manner. Just add them to your application's +classpath, define a component-specific endpoint URI and use it to exchange +messages over the component-specific protocols or APIs. This is possible because +Camel components bind protocol-specific message formats to a Camel-specific +`normalized message format`__. The normalized message format hides +protocol-specific details from Akka and makes it therefore very easy to support +a large number of protocols through a uniform Camel component interface. The +akka-camel module further converts mutable Camel messages into `immutable +representations`__ which are used by Consumer and Producer actors for pattern +matching, transformation, serialization or storage, for example. + +__ https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/main/java/org/apache/camel/Message.java +__ http://github.com/jboner/akka/blob/v0.8/akka-camel/src/main/scala/akka/Message.scala#L17 + + +Dependencies +============ + +Akka's Camel Integration consists of two modules + +* akka-camel - this module depends on akka-actor and camel-core (+ transitive + dependencies) and implements the Camel integration for (untyped) actors + +* akka-camel-typed - this module depends on akka-typed-actor and akka-camel (+ + transitive dependencies) and implements the Camel integration for typed actors + +The akka-camel-typed module is optional. To have both untyped and typed actors +working with Camel, add the following dependencies to your SBT project +definition. + +.. code-block:: scala + + import sbt._ + + class Project(info: ProjectInfo) extends DefaultProject(info) with AkkaProject { + // ... + val akkaCamel = akkaModule("camel") + val akkaCamelTyped = akkaModule("camel-typed") // optional typed actor support + // ... + } + + +.. _camel-consume-messages: + +Consume messages +================ + +Actors (untyped) +---------------- + +For actors (Scala) to receive messages, they must mixin the `Consumer`_ +trait. For example, the following actor class (Consumer1) implements the +endpointUri method, which is declared in the Consumer trait, in order to receive +messages from the ``file:data/input/actor`` Camel endpoint. Untyped actors +(Java) need to extend the abstract UntypedConsumerActor class and implement the +getEndpointUri() and onReceive(Object) methods. + +.. _Consumer: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/Consumer.scala + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.{Message, Consumer} + + class Consumer1 extends Actor with Consumer { + def endpointUri = "file:data/input/actor" + + def receive = { + case msg: Message => println("received %s" format msg.bodyAs[String]) + } + } + +**Java** + +.. code-block:: java + + import akka.camel.Message; + import akka.camel.UntypedConsumerActor; + + public class Consumer1 extends UntypedConsumerActor { + public String getEndpointUri() { + return "file:data/input/actor"; + } + + public void onReceive(Object message) { + Message msg = (Message)message; + String body = msg.getBodyAs(String.class); + System.out.println(String.format("received %s", body)) + } + } + +Whenever a file is put into the data/input/actor directory, its content is +picked up by the Camel `file component`_ and sent as message to the +actor. Messages consumed by actors from Camel endpoints are of type +`Message`_. These are immutable representations of Camel messages. + +.. _file component: http://camel.apache.org/file2.html +.. _Message: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/Message.scala + +For Message usage examples refer to the unit tests: + +* Message unit tests - `Scala API `_ +* Message unit tests - `Java API `_ + +Here's another example that sets the endpointUri to +``jetty:http://localhost:8877/camel/default``. It causes Camel's `Jetty +component`_ to start an embedded `Jetty`_ server, accepting HTTP connections +from localhost on port 8877. + +.. _Jetty component: http://camel.apache.org/jetty.html +.. _Jetty: http://www.eclipse.org/jetty/ + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.{Message, Consumer} + + class Consumer2 extends Actor with Consumer { + def endpointUri = "jetty:http://localhost:8877/camel/default" + + def receive = { + case msg: Message => self.reply("Hello %s" format msg.bodyAs[String]) + } + } + +**Java** + +.. code-block:: java + + import akka.camel.Message; + import akka.camel.UntypedConsumerActor; + + public class Consumer2 extends UntypedConsumerActor { + public String getEndpointUri() { + return "jetty:http://localhost:8877/camel/default"; + } + + public void onReceive(Object message) { + Message msg = (Message)message; + String body = msg.getBodyAs(String.class); + getContext().tryReply(String.format("Hello %s", body)); + } + } + +After starting the actor, clients can send messages to that actor by POSTing to +``http://localhost:8877/camel/default``. The actor sends a response by using the +self.reply method (Scala). For returning a message body and headers to the HTTP +client the response type should be `Message`_. For any other response type, a +new Message object is created by akka-camel with the actor response as message +body. + +.. _Message: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/Message.scala + + +Typed actors +------------ + +Typed actors can also receive messages from Camel endpoints. In contrast to +(untyped) actors, which only implement a single receive or onReceive method, a +typed actor may define several (message processing) methods, each of which can +receive messages from a different Camel endpoint. For a typed actor method to be +exposed as Camel endpoint it must be annotated with the `@consume +annotation`_. For example, the following typed consumer actor defines two +methods, foo and bar. + +.. _@consume annotation: http://github.com/jboner/akka/blob/master/akka-camel/src/main/java/akka/camel/consume.java + +**Scala** + +.. code-block:: scala + + import org.apache.camel.{Body, Header} + import akka.actor.TypedActor + import akka.camel.consume + + trait TypedConsumer1 { + @consume("file:data/input/foo") + def foo(body: String): Unit + + @consume("jetty:http://localhost:8877/camel/bar") + def bar(@Body body: String, @Header("X-Whatever") header: String): String + } + + class TypedConsumer1Impl extends TypedActor with TypedConsumer1 { + def foo(body: String) = println("Received message: %s" format body) + def bar(body: String, header: String) = "body=%s header=%s" format (body, header) + } + +**Java** + +.. code-block:: java + + import org.apache.camel.Body; + import org.apache.camel.Header; + import akka.actor.TypedActor; + import akka.camel.consume; + + public interface TypedConsumer1 { + @consume("file:data/input/foo") + public void foo(String body); + + @consume("jetty:http://localhost:8877/camel/bar") + public String bar(@Body String body, @Header("X-Whatever") String header); + } + + public class TypedConsumer1Impl extends TypedActor implements TypedConsumer1 { + public void foo(String body) { + System.out.println(String.format("Received message: ", body)); + } + + public String bar(String body, String header) { + return String.format("body=%s header=%s", body, header); + } + } + +The foo method can be invoked by placing a file in the data/input/foo +directory. Camel picks up the file from this directory and akka-camel invokes +foo with the file content as argument (converted to a String). Camel +automatically tries to convert messages to appropriate types as defined by the +method parameter(s). The conversion rules are described in detail on the +following pages: + +* `Bean integration `_ +* `Bean binding `_ +* `Parameter binding `_ + +The bar method can be invoked by POSTing a message to +http://localhost:8877/camel/bar. Here, parameter binding annotations are used to +tell Camel how to extract data from the HTTP message. The @Body annotation binds +the HTTP request body to the first parameter, the @Header annotation binds the +X-Whatever header to the second parameter. The return value is sent as HTTP +response message body to the client. + +Parameter binding annotations must be placed on the interface, the @consume +annotation can also be placed on the methods in the implementation class. + + +.. _camel-publishing: + +Consumer publishing +------------------- + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +Publishing a consumer actor at its Camel endpoint occurs when the actor is +started. Publication is done asynchronously; setting up an endpoint (more +precisely, the route from that endpoint to the actor) may still be in progress +after the ActorRef method returned. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor._ + + val actor = actorOf(Props[Consumer1]) // create Consumer actor and activate endpoint in background + +**Java** + +.. code-block:: java + + import static akka.actor.Actors.*; + import akka.actor.ActorRef; + + ActorRef actor = actorOf(new Props(Consumer1.class)); // create Consumer actor and activate endpoint in background + + +Typed actors +^^^^^^^^^^^^ + +Publishing of typed actor methods is done when the typed actor is created with +one of the TypedActor.newInstance(..) methods. Publication is done in the +background here as well i.e. it may still be in progress when +TypedActor.newInstance(..) returns. + +**Scala** + +.. code-block:: scala + + import akka.actor.TypedActor + + // create TypedConsumer1 object and activate endpoint(s) in background + val consumer = TypedActor.newInstance(classOf[TypedConsumer1], classOf[TypedConumer1Impl]) + +**Java** + +.. code-block:: java + + import akka.actor.TypedActor; + + // create TypedConsumer1 object and activate endpoint(s) in background + TypedConsumer1 consumer = TypedActor.newInstance(TypedConsumer1.class, TypedConumer1Impl.class); + + +.. _camel-consumers-and-camel-service: + +Consumers and the CamelService +------------------------------ + +Publishing of consumer actors or typed actor methods requires a running +CamelService. The Akka :ref:`microkernel` can start a CamelService automatically +(see :ref:`camel-configuration`). When using Akka in other environments, a +CamelService must be started manually. Applications can do that by calling the +CamelServiceManager.startCamelService method. + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + + startCamelService + +**Java** + +.. code-block:: java + + import static akka.camel.CamelServiceManager.*; + + startCamelService(); + +If applications need to wait for a certain number of consumer actors or typed +actor methods to be published they can do so with the +``CamelServiceManager.mandatoryService.awaitEndpointActivation`` method, where +``CamelServiceManager.mandatoryService`` is the current CamelService instance +(or throws an IllegalStateException there's no current CamelService). + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + + startCamelService + + // Wait for three conumer endpoints to be activated + mandatoryService.awaitEndpointActivation(3) { + // Start three consumer actors (for example) + // ... + } + + // Communicate with consumer actors via their activated endpoints + // ... + +**Java** + +.. code-block:: java + + import akka.japi.SideEffect; + import static akka.camel.CamelServiceManager.*; + + startCamelService(); + + // Wait for three conumer endpoints to be activated + getMandatoryService().awaitEndpointActivation(3, new SideEffect() { + public void apply() { + // Start three consumer actors (for example) + // ... + } + }); + + // Communicate with consumer actors via their activated endpoints + // ... + +Alternatively, one can also use ``Option[CamelService]`` returned by +``CamelServiceManager.service``. + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + + startCamelService + + for(s <- service) s.awaitEndpointActivation(3) { + // ... + } + +**Java** + +.. code-block:: java + + import java.util.concurrent.CountDownLatch; + + import akka.camel.CamelService; + import static akka.camel.CamelServiceManager.*; + + startCamelService(); + + for (CamelService s : getService()) s.awaitEndpointActivation(3, new SideEffect() { + public void apply() { + // ... + } + }); + +:ref:`camel-configuration` additionally describes how a CamelContext, that is +managed by a CamelService, can be cutomized before starting the service. When +the CamelService is no longer needed, it should be stopped. + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + + stopCamelService + +**Java** + +.. code-block:: java + + import static akka.camel.CamelServiceManager.*; + + stopCamelService(); + + +.. _camel-unpublishing: + +Consumer un-publishing +---------------------- + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +When an actor is stopped, the route from the endpoint to that actor is stopped +as well. For example, stopping an actor that has been previously published at +``http://localhost:8877/camel/test`` will cause a connection failure when trying +to access that endpoint. Stopping the route is done asynchronously; it may be +still in progress after the ``ActorRef.stop`` method returned. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor._ + + val actor = actorOf(Props[Consumer1]) // create Consumer actor + actor // activate endpoint in background + // ... + actor.stop // deactivate endpoint in background + +**Java** + +.. code-block:: java + + import static akka.actor.Actors.*; + import akka.actor.ActorRef; + + ActorRef actor = actorOf(new Props(Consumer1.class)); // create Consumer actor and activate endpoint in background + // ... + actor.stop(); // deactivate endpoint in background + + +Typed actors +^^^^^^^^^^^^ + +When a typed actor is stopped, routes to @consume annotated methods of this +typed actors are stopped as well. Stopping the routes is done asynchronously; it +may be still in progress after the TypedActor.stop method returned. + +**Scala** + +.. code-block:: scala + + import akka.actor.TypedActor + + // create TypedConsumer1 object and activate endpoint(s) in background + val consumer = TypedActor.newInstance(classOf[TypedConsumer1], classOf[TypedConumer1Impl]) + + // deactivate endpoints in background + TypedActor.stop(consumer) + +**Java** + +.. code-block:: java + + import akka.actor.TypedActor; + + // Create typed consumer actor and activate endpoints in background + TypedConsumer1 consumer = TypedActor.newInstance(TypedConsumer1.class, TypedConumer1Impl.class); + + // Deactivate endpoints in background + TypedActor.stop(consumer); + + +.. _camel-acknowledgements: + +Acknowledgements +---------------- + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +With in-out message exchanges, clients usually know that a message exchange is +done when they receive a reply from a consumer actor. The reply message can be a +Message (or any object which is then internally converted to a Message) on +success, and a Failure message on failure. + +With in-only message exchanges, by default, an exchange is done when a message +is added to the consumer actor's mailbox. Any failure or exception that occurs +during processing of that message by the consumer actor cannot be reported back +to the endpoint in this case. To allow consumer actors to positively or +negatively acknowledge the receipt of a message from an in-only message +exchange, they need to override the ``autoack`` (Scala) or ``isAutoack`` (Java) +method to return false. In this case, consumer actors must reply either with a +special Ack message (positive acknowledgement) or a Failure (negative +acknowledgement). + +**Scala** + +.. code-block:: scala + + import akka.camel.{Ack, Failure} + // ... other imports omitted + + class Consumer3 extends Actor with Consumer { + override def autoack = false + + def endpointUri = "jms:queue:test" + + def receive = { + // ... + self.reply(Ack) // on success + // ... + self.reply(Failure(...)) // on failure + } + } + +**Java** + +.. code-block:: java + + import akka.camel.Failure + import static akka.camel.Ack.ack; + // ... other imports omitted + + public class Consumer3 extends UntypedConsumerActor { + + public String getEndpointUri() { + return "jms:queue:test"; + } + + public boolean isAutoack() { + return false; + } + + public void onReceive(Object message) { + // ... + getContext().reply(ack()) // on success + // ... + val e: Exception = ... + getContext().reply(new Failure(e)) // on failure + } + } + + +.. _camel-blocking-exchanges: + +Blocking exchanges +------------------ + +By default, message exchanges between a Camel endpoint and a consumer actor are +non-blocking because, internally, the ! (bang) operator is used to commicate +with the actor. The route to the actor does not block waiting for a reply. The +reply is sent asynchronously (see also :ref:`camel-asynchronous-routing`). +Consumer actors however can be configured to make this interaction blocking. + +**Scala** + +.. code-block:: scala + + class ExampleConsumer extends Actor with Consumer { + override def blocking = true + + def endpointUri = ... + def receive = { + // ... + } + } + +**Java** + +.. code-block:: java + + public class ExampleConsumer extends UntypedConsumerActor { + + public boolean isBlocking() { + return true; + } + + public String getEndpointUri() { + // ... + } + + public void onReceive(Object message) { + // ... + } + } + +In this case, the ``!!`` (bangbang) operator is used internally to communicate +with the actor which blocks a thread until the consumer sends a response or +throws an exception within receive. Although it may decrease scalability, this +setting can simplify error handling (see `this article`_) or allows timeout +configurations on actor-level (see :ref:`camel-timeout`). + +.. _this article: http://krasserm.blogspot.com/2011/02/akka-consumer-actors-new-features-and.html + + +.. _camel-timeout: + +Consumer timeout +---------------- + +Endpoints that support two-way communications need to wait for a response from +an (untyped) actor or typed actor before returning it to the initiating client. +For some endpoint types, timeout values can be defined in an endpoint-specific +way which is described in the documentation of the individual `Camel +components`_. Another option is to configure timeouts on the level of consumer +actors and typed consumer actors. + +.. _Camel components: http://camel.apache.org/components.html + + +Typed actors +^^^^^^^^^^^^ + +For typed actors, timeout values for method calls that return a result can be +set when the typed actor is created. In the following example, the timeout is +set to 20 seconds (default is 5 seconds). + +**Scala** + +.. code-block:: scala + + import akka.actor.TypedActor + + val consumer = TypedActor.newInstance(classOf[TypedConsumer1], classOf[TypedConumer1Impl], 20000 /* 20 seconds */) + +**Java** + +.. code-block:: java + + import akka.actor.TypedActor; + + TypedConsumer1 consumer = TypedActor.newInstance(TypedConsumer1.class, TypedConumer1Impl.class, 20000 /* 20 seconds */); + + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +Two-way communications between a Camel endpoint and an (untyped) actor are +initiated by sending the request message to the actor with the ``!`` (bang) +operator and the actor replies to the endpoint when the response is ready. In +order to support timeouts on actor-level, endpoints need to send the request +message with the ``!!`` (bangbang) operator for which a timeout value is +applicable. This can be achieved by overriding the Consumer.blocking method to +return true. + +**Scala** + +.. code-block:: scala + + class Consumer2 extends Actor with Consumer { + self.timeout = 20000 // timeout set to 20 seconds + + override def blocking = true + + def endpointUri = "direct:example" + + def receive = { + // ... + } + } + +**Java** + +.. code-block:: java + + public class Consumer2 extends UntypedConsumerActor { + + public Consumer2() { + getContext().setTimeout(20000); // timeout set to 20 seconds + } + + public String getEndpointUri() { + return "direct:example"; + } + + public boolean isBlocking() { + return true; + } + + public void onReceive(Object message) { + // ... + } + } + +This is a valid approach for all endpoint types that do not "natively" support +asynchronous two-way message exchanges. For all other endpoint types (like +`Jetty`_ endpoints) is it not recommended to switch to blocking mode but rather +to configure timeouts in an endpoint-specific way (see +also :ref:`camel-asynchronous-routing`). + + +Remote consumers +---------------- + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +Publishing of remote consumer actors is always done on the server side, local +proxies are never published. Hence the CamelService must be started on the +remote node. For example, to publish an (untyped) actor on a remote node at +endpoint URI ``jetty:http://localhost:6644/remote-actor-1``, define the +following consumer actor class. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.annotation.consume + import akka.camel.Consumer + + class RemoteActor1 extends Actor with Consumer { + def endpointUri = "jetty:http://localhost:6644/remote-actor-1" + + protected def receive = { + case msg => self.reply("response from remote actor 1") + } + } + +**Java** + +.. code-block:: java + + import akka.camel.UntypedConsumerActor; + + public class RemoteActor1 extends UntypedConsumerActor { + public String getEndpointUri() { + return "jetty:http://localhost:6644/remote-actor-1"; + } + + public void onReceive(Object message) { + getContext().tryReply("response from remote actor 1"); + } + } + +On the remote node, start a `CamelService`_, start a remote server, create the +actor and register it at the remote server. + +.. _CamelService: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/CamelService.scala + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + import akka.actor.Actor._ + import akka.actor.ActorRef + + // ... + startCamelService + + val consumer = val consumer = actorOf(Props[RemoteActor1]) + + remote.start("localhost", 7777) + remote.register(consumer) // register and start remote consumer + // ... + +**Java** + +.. code-block:: java + + import akka.camel.CamelServiceManager; + import static akka.actor.Actors.*; + + // ... + CamelServiceManager.startCamelService(); + + ActorRef actor = actorOf(new Props(RemoteActor1.class)); + + remote().start("localhost", 7777); + remote().register(actor); // register and start remote consumer + // ... + +Explicitly starting a CamelService can be omitted when Akka is running in Kernel +mode, for example (see also :ref:`camel-configuration`). + + +Typed actors +^^^^^^^^^^^^ + +Remote typed consumer actors can be registered with one of the +``registerTyped*`` methods on the remote server. The following example registers +the actor with the custom id "123". + +**Scala** + +.. code-block:: scala + + import akka.actor.TypedActor + + // ... + val obj = TypedActor.newRemoteInstance( + classOf[SampleRemoteTypedConsumer], + classOf[SampleRemoteTypedConsumerImpl]) + + remote.registerTypedActor("123", obj) + // ... + +**Java** + +.. code-block:: java + + import akka.actor.TypedActor; + + SampleRemoteTypedConsumer obj = (SampleRemoteTypedConsumer)TypedActor.newInstance( + SampleRemoteTypedConsumer.class, + SampleRemoteTypedConsumerImpl.class); + + remote.registerTypedActor("123", obj) + // ... + + +Produce messages +================ + +A minimum pre-requisite for producing messages to Camel endpoints with producer +actors (see below) is an initialized and started CamelContextManager. + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelContextManager + + CamelContextManager.init // optionally takes a CamelContext as argument + CamelContextManager.start // starts the managed CamelContext + +**Java** + +.. code-block:: java + + import akka.camel.CamelContextManager; + + CamelContextManager.init(); // optionally takes a CamelContext as argument + CamelContextManager; // starts the managed CamelContext + +For using producer actors, application may also start a CamelService. This will +not only setup a CamelContextManager behind the scenes but also register +listeners at the actor registry (needed to publish consumer actors). If your +application uses producer actors only and you don't want to have the (very +small) overhead generated by the registry listeners then setting up a +CamelContextManager without starting CamelService is recommended. Otherwise, +just start a CamelService as described for consumer +actors: :ref:`camel-consumers-and-camel-service`. + + +Producer trait +-------------- + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +For sending messages to Camel endpoints, actors + +* written in Scala need to mixin the `Producer`_ trait and implement the + endpointUri method. + +* written in Java need to extend the abstract UntypedProducerActor class and + implement the getEndpointUri() method. By extending the UntypedProducerActor + class, untyped actors (Java) inherit the behaviour of the Producer trait. + +.. _Producer: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/Producer.scala + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.Producer + + class Producer1 extends Actor with Producer { + def endpointUri = "http://localhost:8080/news" + } + +**Java** + +.. code-block:: java + + import akka.camel.UntypedProducerActor; + + public class Producer1 extends UntypedProducerActor { + public String getEndpointUri() { + return "http://localhost:8080/news"; + } + } + +Producer1 inherits a default implementation of the receive method from the +Producer trait. To customize a producer actor's default behavior it is +recommended to override the Producer.receiveBeforeProduce and +Producer.receiveAfterProduce methods. This is explained later in more detail. +Actors should not override the default Producer.receive method. + +Any message sent to a Producer actor (or UntypedProducerActor) will be sent to +the associated Camel endpoint, in the above example to +``http://localhost:8080/news``. Response messages (if supported by the +configured endpoint) will, by default, be returned to the original sender. The +following example uses the ``?`` operator (Scala) to send a message to a +Producer actor and waits for a response. In Java, the sendRequestReply method is +used. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor._ + import akka.actor.ActorRef + + val producer = actorOf(Props[Producer1]) + val response = (producer ? "akka rocks").get + val body = response.bodyAs[String] + +**Java** + +.. code-block:: java + + import akka.actor.ActorRef; + import static akka.actor.Actors.*; + import akka.camel.Message; + + ActorRef producer = actorOf(new Props(Producer1.class)); + Message response = (Message)producer.sendRequestReply("akka rocks"); + String body = response.getBodyAs(String.class) + +If the message is sent using the ! operator (or the tell method in Java) +then the response message is sent back asynchronously to the original sender. In +the following example, a Sender actor sends a message (a String) to a producer +actor using the ! operator and asynchronously receives a response (of type +Message). + +**Scala** + +.. code-block:: scala + + import akka.actor.{Actor, ActorRef} + import akka.camel.Message + + class Sender(producer: ActorRef) extends Actor { + def receive = { + case request: String => producer ! request + case response: Message => { + /* process response ... */ + } + // ... + } + } + +**Java** + +.. code-block:: java + + // TODO + + +.. _camel-custom-processing: + +Custom Processing +^^^^^^^^^^^^^^^^^ + +Instead of replying to the initial sender, producer actors can implement custom +reponse processing by overriding the receiveAfterProduce method (Scala) or +onReceiveAfterProduce method (Java). In the following example, the reponse +message is forwarded to a target actor instead of being replied to the original +sender. + +**Scala** + +.. code-block:: scala + + import akka.actor.{Actor, ActorRef} + import akka.camel.Producer + + class Producer1(target: ActorRef) extends Actor with Producer { + def endpointUri = "http://localhost:8080/news" + + override protected def receiveAfterProduce = { + // do not reply but forward result to target + case msg => target forward msg + } + } + +**Java** + +.. code-block:: java + + import akka.actor.ActorRef; + import akka.camel.UntypedProducerActor; + + public class Producer1 extends UntypedProducerActor { + private ActorRef target; + + public Producer1(ActorRef target) { + this.target = target; + } + + public String getEndpointUri() { + return "http://localhost:8080/news"; + } + + @Override + public void onReceiveAfterProduce(Object message) { + target.forward((Message)message, getContext()); + } + } + +To create an untyped actor instance with a constructor argument, a factory is +needed (this should be doable without a factory in upcoming Akka versions). + +.. code-block:: java + + import akka.actor.ActorRef; + import akka.actor.UntypedActorFactory; + import akka.actor.UntypedActor; + + public class Producer1Factory implements UntypedActorFactory { + + private ActorRef target; + + public Producer1Factory(ActorRef target) { + this.target = target; + } + + public UntypedActor create() { + return new Producer1(target); + } + } + +The instanitation is done with the Actors.actorOf method and the factory as +argument. + +.. code-block:: java + + import static akka.actor.Actors.*; + import akka.actor.ActorRef; + + ActorRef target = ... + ActorRef producer = actorOf(Props(new Producer1Factory(target))); + producer; + +Before producing messages to endpoints, producer actors can pre-process them by +overriding the receiveBeforeProduce method (Scala) or onReceiveBeforeProduce +method (Java). + +**Scala** + +.. code-block:: scala + + import akka.actor.{Actor, ActorRef} + import akka.camel.{Message, Producer} + + class Producer1(target: ActorRef) extends Actor with Producer { + def endpointUri = "http://localhost:8080/news" + + override protected def receiveBeforeProduce = { + case msg: Message => { + // do some pre-processing (e.g. add endpoint-specific message headers) + // ... + + // and return the modified message + msg + } + } + } + +**Java** + +.. code-block:: java + + import akka.actor.ActorRef; + import akka.camel.Message + import akka.camel.UntypedProducerActor; + + public class Producer1 extends UntypedProducerActor { + private ActorRef target; + + public Producer1(ActorRef target) { + this.target = target; + } + + public String getEndpointUri() { + return "http://localhost:8080/news"; + } + + @Override + public Object onReceiveBeforeProduce(Object message) { + Message msg = (Message)message; + // do some pre-processing (e.g. add endpoint-specific message headers) + // ... + + // and return the modified message + return msg + } + } + + +Producer configuration options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The interaction of producer actors with Camel endpoints can be configured to be +one-way or two-way (by initiating in-only or in-out message exchanges, +respectively). By default, the producer initiates an in-out message exchange +with the endpoint. For initiating an in-only exchange, producer actors + +* written in Scala either have to override the oneway method to return true +* written in Java have to override the isOneway method to return true. + +**Scala** + +.. code-block:: scala + + import akka.camel.Producer + + class Producer2 extends Actor with Producer { + def endpointUri = "jms:queue:test" + override def oneway = true + } + +**Java** + +.. code-block:: java + + import akka.camel.UntypedProducerActor; + + public class SampleUntypedReplyingProducer extends UntypedProducerActor { + public String getEndpointUri() { + return "jms:queue:test"; + } + + @Override + public boolean isOneway() { + return true; + } + } + +Message correlation +^^^^^^^^^^^^^^^^^^^ + +To correlate request with response messages, applications can set the +Message.MessageExchangeId message header. + +**Scala** + +.. code-block:: scala + + import akka.camel.Message + + producer ! Message("bar", Map(Message.MessageExchangeId -> "123")) + +**Java** + +.. code-block:: java + + // TODO + +Responses of type Message or Failure will contain that header as well. When +receiving messages from Camel endpoints this message header is already set (see +:ref:`camel-consume-messages`). + + +Matching responses +^^^^^^^^^^^^^^^^^^ + +The following code snippet shows how to best match responses when sending +messages with the ``?`` operator (Scala) or with the ``ask`` method +(Java). + +**Scala** + +.. code-block:: scala + + val response = (producer ? message).get + + response match { + case Some(Message(body, headers)) => ... + case Some(Failure(exception, headers)) => ... + case _ => ... + } + +**Java** + +.. code-block:: java + + // TODO + + +ProducerTemplate +---------------- + +The `Producer`_ trait (and the abstract UntypedProducerActor class) is a very +convenient way for actors to produce messages to Camel endpoints. (Untyped) +actors and typed actors may also use a Camel `ProducerTemplate`_ for producing +messages to endpoints. For typed actors it's the only way to produce messages to +Camel endpoints. + +At the moment, only the Producer trait fully supports asynchronous in-out +message exchanges with Camel endpoints without allocating a thread for the full +duration of the exchange. For example, when using endpoints that support +asynchronous message exchanges (such as Jetty endpoints that internally use +`Jetty's asynchronous HTTP client`_) then usage of the Producer trait is highly +recommended (see also :ref:`camel-asynchronous-routing`). + +.. _Producer: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/Producer.scala +.. _ProducerTemplate: http://camel.apache.org/maven/camel-2.2.0/camel-core/apidocs/index.html +.. _Jetty's asynchronous HTTP client: http://wiki.eclipse.org/Jetty/Tutorial/HttpClient + + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +A managed ProducerTemplate instance can be obtained via +CamelContextManager.mandatoryTemplate. In the following example, an actor uses a +ProducerTemplate to send a one-way message to a ``direct:news`` endpoint. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.CamelContextManager + + class ProducerActor extends Actor { + protected def receive = { + // one-way message exchange with direct:news endpoint + case msg => CamelContextManager.mandatoryTemplate.sendBody("direct:news", msg) + } + } + +**Java** + +.. code-block:: java + + import akka.actor.UntypedActor; + import akka.camel.CamelContextManager; + + public class SampleUntypedActor extends UntypedActor { + public void onReceive(Object msg) { + CamelContextManager.getMandatoryTemplate().sendBody("direct:news", msg); + } + } + +Alternatively, one can also use ``Option[ProducerTemplate]`` returned by +``CamelContextManager.template``. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.CamelContextManager + + class ProducerActor extends Actor { + protected def receive = { + // one-way message exchange with direct:news endpoint + case msg => for(t <- CamelContextManager.template) t.sendBody("direct:news", msg) + } + } + +**Java** + +.. code-block:: java + + import org.apache.camel.ProducerTemplate + + import akka.actor.UntypedActor; + import akka.camel.CamelContextManager; + + public class SampleUntypedActor extends UntypedActor { + public void onReceive(Object msg) { + for (ProducerTemplate t : CamelContextManager.getTemplate()) { + t.sendBody("direct:news", msg); + } + } + } + +For initiating a a two-way message exchange, one of the +``ProducerTemplate.request*`` methods must be used. + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.CamelContextManager + + class ProducerActor extends Actor { + protected def receive = { + // two-way message exchange with direct:news endpoint + case msg => self.reply(CamelContextManager.mandatoryTemplate.requestBody("direct:news", msg)) + } + } + +**Java** + +.. code-block:: java + + import akka.actor.UntypedActor; + import akka.camel.CamelContextManager; + + public class SampleUntypedActor extends UntypedActor { + public void onReceive(Object msg) { + getContext().tryReply(CamelContextManager.getMandatoryTemplate().requestBody("direct:news", msg)); + } + } + + +Typed actors +^^^^^^^^^^^^ + +Typed Actors get access to a managed ProducerTemplate in the same way, as shown +in the next example. + +**Scala** + +.. code-block:: scala + + // TODO + +**Java** + +.. code-block:: java + + import akka.actor.TypedActor; + import akka.camel.CamelContextManager; + + public class SampleProducerImpl extends TypedActor implements SampleProducer { + public void foo(String msg) { + ProducerTemplate template = CamelContextManager.getMandatoryTemplate(); + template.sendBody("direct:news", msg); + } + } + + +.. _camel-asynchronous-routing: + +Asynchronous routing +==================== + +Since Akka 0.10, in-out message exchanges between endpoints and actors are +designed to be asynchronous. This is the case for both, consumer and producer +actors. + +* A consumer endpoint sends request messages to its consumer actor using the ``!`` + (bang) operator and the actor returns responses with self.reply once they are + ready. The sender reference used for reply is an adapter to Camel's asynchronous + routing engine that implements the ActorRef trait. + +* A producer actor sends request messages to its endpoint using Camel's + asynchronous routing engine. Asynchronous responses are wrapped and added to the + producer actor's mailbox for later processing. By default, response messages are + returned to the initial sender but this can be overridden by Producer + implementations (see also description of the ``receiveAfterProcessing`` method + in :ref:`camel-custom-processing`). + +However, asynchronous two-way message exchanges, without allocating a thread for +the full duration of exchange, cannot be generically supported by Camel's +asynchronous routing engine alone. This must be supported by the individual +`Camel components`_ (from which endpoints are created) as well. They must be +able to suspend any work started for request processing (thereby freeing threads +to do other work) and resume processing when the response is ready. This is +currently the case for a `subset of components`_ such as the `Jetty component`_. +All other Camel components can still be used, of course, but they will cause +allocation of a thread for the duration of an in-out message exchange. There's +also a :ref:`camel-async-example` that implements both, an asynchronous +consumer and an asynchronous producer, with the jetty component. + +.. _Camel components: http://camel.apache.org/components.html +.. _subset of components: http://camel.apache.org/asynchronous-routing-engine.html +.. _Jetty component: http://camel.apache.org/jetty.html + + +Fault tolerance +=============== + +Consumer actors and typed actors can be also managed by supervisors. If a +consumer is configured to be restarted upon failure the associated Camel +endpoint is not restarted. It's behaviour during restart is as follows. + +* A one-way (in-only) message exchange will be queued by the consumer and + processed once restart completes. + +* A two-way (in-out) message exchange will wait and either succeed after restart + completes or time-out when the restart duration exceeds + the :ref:`camel-timeout`. + +If a consumer is configured to be shut down upon failure, the associated +endpoint is shut down as well. For details refer to :ref:`camel-unpublishing`. + +For examples, tips and trick how to implement fault-tolerant consumer and +producer actors, take a look at these two articles. + +* `Akka Consumer Actors: New Features and Best Practices `_ +* `Akka Producer Actors: New Features and Best Practices `_ + + +.. _camel-configuration: + +CamelService configuration +========================== + +For publishing consumer actors and typed actor methods +(:ref:`camel-publishing`), applications must start a CamelService. When starting +Akka in :ref:`microkernel` mode then a CamelService can be started automatically +when camel is added to the enabled-modules list in :ref:`configuration`, for example: + +.. code-block:: none + + akka { + ... + enabled-modules = ["camel"] # Options: ["remote", "camel", "http"] + ... + } + +Applications that do not use the Akka Kernel, such as standalone applications +for example, need to start a CamelService manually, as explained in the +following subsections.When starting a CamelService manually, settings in +:ref:`configuration` are ignored. + + +Standalone applications +----------------------- + +Standalone application should create and start a CamelService in the following way. + +**Scala** + +.. code-block:: scala + + import akka.camel.CamelServiceManager._ + + startCamelService + +**Java** + +.. code-block:: java + + import static akka.camel.CamelServiceManager.*; + + startCamelService(); + +Internally, a CamelService uses the CamelContextManager singleton to manage a +CamelContext. A CamelContext manages the routes from endpoints to consumer +actors and typed actors. These routes are added and removed at runtime (when +(untyped) consumer actors and typed consumer actors are started and stopped). +Applications may additionally want to add their own custom routes or modify the +CamelContext in some other way. This can be done by initializing the +CamelContextManager manually and making modifications to CamelContext **before** +the CamelService is started. + +**Scala** + +.. code-block:: scala + + import org.apache.camel.builder.RouteBuilder + + import akka.camel.CamelContextManager + import akka.camel.CamelServiceManager._ + + CamelContextManager.init + + // add a custom route to the managed CamelContext + CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) + + startCamelService + + // an application-specific route builder + class CustomRouteBuilder extends RouteBuilder { + def configure { + // ... + } + } + +**Java** + +.. code-block:: java + + import org.apache.camel.builder.RouteBuilder; + + import akka.camel.CamelContextManager; + import static akka.camel.CamelServiceManager.*; + + CamelContextManager.init(); + + // add a custom route to the managed CamelContext + CamelContextManager.getMandatoryContext().addRoutes(new CustomRouteBuilder()); + + startCamelService(); + + // an application-specific route builder + private static class CustomRouteBuilder extends RouteBuilder { + public void configure() { + // ... + } + } + + +Applications may even provide their own CamelContext instance as argument to the +init method call as shown in the following snippet. Here, a DefaultCamelContext +is created using a Spring application context as `registry`_. + +.. _registry: http://camel.apache.org/registry.html + + +**Scala** + +.. code-block:: scala + + import org.apache.camel.impl.DefaultCamelContext + import org.apache.camel.spring.spi.ApplicationContextRegistry + import org.springframework.context.support.ClassPathXmlApplicationContext + + import akka.camel.CamelContextManager + import akka.camel.CamelServiceManager._ + + // create a custom Camel registry backed up by a Spring application context + val context = new ClassPathXmlApplicationContext("/context.xml") + val registry = new ApplicationContextRegistry(context) + + // initialize CamelContextManager with a DefaultCamelContext using the custom registry + CamelContextManager.init(new DefaultCamelContext(registry)) + + // ... + + startCamelService + +**Java** + +.. code-block:: java + + import org.apache.camel.impl.DefaultCamelContext + import org.apache.camel.spi.Registry; + import org.apache.camel.spring.spi.ApplicationContextRegistry; + + import org.springframework.context.ApplicationContext; + import org.springframework.context.support.ClassPathXmlApplicationContext; + + import akka.camel.CamelContextManager; + import static akka.camel.CamelServiceManager.*; + + // create a custom Camel registry backed up by a Spring application context + ApplicationContext context = new ClassPathXmlApplicationContext("/context.xml"); + Registry registry = new ApplicationContextRegistry(context); + + // initialize CamelContextManager with a DefaultCamelContext using the custom registry + CamelContextManager.init(new DefaultCamelContext(registry)); + + // ... + + startCamelService(); + + +.. _camel-spring-applications: + +Standalone Spring applications +------------------------------ + +A better approach to configure a Spring application context as registry for the +CamelContext is to use `Camel's Spring support`_. Furthermore, +the :ref:`spring-module` module additionally supports a element +for creating and starting a CamelService. An optional reference to a custom +CamelContext can be defined for as well. Here's an example. + +.. _Camel's Spring support: http://camel.apache.org/spring.html + +.. code-block:: xml + + + + + + + + + + + + + + + + + +Creating a CamelContext this way automatically adds the defining Spring +application context as registry to that CamelContext. The CamelService is +started when the application context is started and stopped when the application +context is closed. A simple usage example is shown in the following snippet. + +**Scala** + +.. code-block:: scala + + import org.springframework.context.support.ClassPathXmlApplicationContext + import akka.camel.CamelContextManager + + // Create and start application context (start CamelService) + val appctx = new ClassPathXmlApplicationContext("/context.xml") + + // Access to CamelContext (SpringCamelContext) + val ctx = CamelContextManager.mandatoryContext + // Access to ProducerTemplate of that CamelContext + val tpl = CamelContextManager.mandatoryTemplate + + // use ctx and tpl ... + + // Close application context (stop CamelService) + appctx.close + +**Java** + +.. code-block:: java + + // TODO + + +If the CamelService doesn't reference a custom CamelContext then a +DefaultCamelContext is created (and accessible via the CamelContextManager). + +.. code-block:: xml + + + + + + + + + +Kernel mode +----------- + +For classes that are loaded by the Kernel or the Initializer, starting the +CamelService can be omitted, as discussed in the previous section. Since these +classes are loaded and instantiated before the CamelService is started (by +Akka), applications can make modifications to a CamelContext here as well (and +even provide their own CamelContext). Assuming there's a boot class +sample.camel.Boot configured in :ref:`configuration`. + +.. code-block:: none + + akka { + ... + boot = ["sample.camel.Boot"] + ... + } + +Modifications to the CamelContext can be done like in the following snippet. + +**Scala** + +.. code-block:: scala + + package sample.camel + + import org.apache.camel.builder.RouteBuilder + + import akka.camel.CamelContextManager + + class Boot { + CamelContextManager.init + + // Customize CamelContext with application-specific routes + CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) + + // No need to start CamelService here. It will be started + // when this classes has been loaded and instantiated. + } + + class CustomRouteBuilder extends RouteBuilder { + def configure { + // ... + } + } + +**Java** + +.. code-block:: java + + // TODO + + +Custom Camel routes +=================== + +In all the examples so far, routes to consumer actors have been automatically +constructed by akka-camel, when the actor was started. Although the default +route construction templates, used by akka-camel internally, are sufficient for +most use cases, some applications may require more specialized routes to actors. +The akka-camel module provides two mechanisms for customizing routes to actors, +which will be explained in this section. These are + +* Usage of :ref:`camel-components` to access (untyped) actor and actors. + Any Camel route can use these components to access Akka actors. + +* :ref:`camel-intercepting-route-construction` to (untyped) actor and actors. + Default routes to consumer actors are extended using predefined extension + points. + + +.. _camel-components: + +Akka Camel components +--------------------- + +Akka actors can be access from Camel routes using the `actor`_ and +`typed-actor`_ Camel components, respectively. These components can be used to +access any Akka actor (not only consumer actors) from Camel routes, as described +in the following sections. + +.. _actor: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/component/ActorComponent.scala +.. _typed-actor: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/component/TypedActorComponent.scala + + +Access to actors +---------------- + +To access (untyped) actors from custom Camel routes, the `actor`_ Camel +component should be used. It fully supports Camel's `asynchronous routing +engine`_. + +.. _actor: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/component/ActorComponent.scala +.. _asynchronous routing engine: http://camel.apache.org/asynchronous-routing-engine.html + +This component accepts the following enpoint URI formats: + +* ``actor:[?]`` +* ``actor:id:[][?]`` +* ``actor:uuid:[][?]`` + +where ```` and ```` refer to ``actorRef.id`` and the +String-representation of ``actorRef.uuid``, respectively. The ```` are +name-value pairs separated by ``&`` (i.e. ``name1=value1&name2=value2&...``). + + +URI options +^^^^^^^^^^^ + +The following URI options are supported: + ++----------+---------+---------+-------------------------------------------+ +| Name | Type | Default | Description | ++==========+=========+=========+===========================================+ +| blocking | Boolean | false | If set to true, in-out message exchanges | +| | | | with the target actor will be made with | +| | | | the ``!!`` operator, otherwise with the | +| | | | ``!`` operator. | +| | | | | +| | | | See also :ref:`camel-timeout`. | ++----------+---------+---------+-------------------------------------------+ +| autoack | Boolean | true | If set to true, in-only message exchanges | +| | | | are auto-acknowledged when the message is | +| | | | added to the actor's mailbox. If set to | +| | | | false, actors must acknowledge the | +| | | | receipt of the message. | +| | | | | +| | | | See also :ref:`camel-acknowledgements`. | ++----------+---------+---------+-------------------------------------------+ + +Here's an actor endpoint URI example containing an actor uuid:: + + actor:uuid:12345678?blocking=true + +In actor endpoint URIs that contain id: or uuid:, an actor identifier (id or +uuid) is optional. In this case, the in-message of an exchange produced to an +actor endpoint must contain a message header with name CamelActorIdentifier +(which is defined by the ActorComponent.ActorIdentifier field) and a value that +is the target actor's identifier. On the other hand, if the URI contains an +actor identifier, it can be seen as a default actor identifier that can be +overridden by messages containing a CamelActorIdentifier header. + + +Message headers +^^^^^^^^^^^^^^^ + ++----------------------+--------+-------------------------------------------+ +| Name | Type | Description | ++======================+========+===========================================+ +| CamelActorIdentifier | String | Contains the identifier (id or uuid) of | +| | | the actor to route the message to. The | +| | | identifier is interpreted as actor id if | +| | | the URI contains id:, the identifier is | +| | | interpreted as uuid id the URI contains | +| | | uuid:. A uuid value may also be of type | +| | | Uuid (not only String). The header name | +| | | is defined by the | +| | | ActorComponent.ActorIdentifier field. | ++----------------------+--------+-------------------------------------------+ + +Here's another actor endpoint URI example that doesn't define an actor uuid. In +this case the target actor uuid must be defined by the CamelActorIdentifier +message header:: + + actor:uuid: + +In the following example, a custom route to an actor is created, using the +actor's uuid (i.e. actorRef.uuid). The route starts from a `Jetty`_ endpoint and +ends at the target actor. + + +**Scala** + +.. code-block:: scala + + import org.apache.camel.builder.RouteBuilder + + import akka.actor._ + import akka.actor.Actor + import akka.actor.Actor._ + import akka.camel.{Message, CamelContextManager, CamelServiceManager} + + object CustomRouteExample extends Application { + val target = actorOf(Props[CustomRouteTarget]) + + CamelServiceManager.startCamelService + CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder(target.uuid)) + } + + class CustomRouteTarget extends Actor { + def receive = { + case msg: Message => self.reply("Hello %s" format msg.bodyAs[String]) + } + } + + class CustomRouteBuilder(uuid: Uuid) extends RouteBuilder { + def configure { + val actorUri = "actor:uuid:%s" format uuid + from("jetty:http://localhost:8877/camel/custom").to(actorUri) + } + } + + +**Java** + +.. code-block:: java + + import com.eaio.uuid.UUID; + + import org.apache.camel.builder.RouteBuilder; + import static akka.actor.Actors.*; + import akka.actor.ActorRef; + import akka.actor.UntypedActor; + import akka.camel.CamelServiceManager; + import akka.camel.CamelContextManager; + import akka.camel.Message; + + public class CustomRouteExample { + public static void main(String... args) throws Exception { + ActorRef target = actorOf(new Props(CustomRouteTarget.class)); + CamelServiceManager.startCamelService(); + CamelContextManager.getMandatoryContext().addRoutes(new CustomRouteBuilder(target.getUuid())); + } + } + + public class CustomRouteTarget extends UntypedActor { + public void onReceive(Object message) { + Message msg = (Message) message; + String body = msg.getBodyAs(String.class); + getContext().tryReply(String.format("Hello %s", body)); + } + } + + public class CustomRouteBuilder extends RouteBuilder { + private UUID uuid; + + public CustomRouteBuilder(UUID uuid) { + this.uuid = uuid; + } + + public void configure() { + String actorUri = String.format("actor:uuid:%s", uuid); + from("jetty:http://localhost:8877/camel/custom").to(actorUri); + } + } + +When the example is started, messages POSTed to +``http://localhost:8877/camel/custom`` are routed to the target actor. + + +Access to typed actors +---------------------- + +To access typed actor methods from custom Camel routes, the `typed-actor`_ Camel +component should be used. It is a specialization of the Camel `bean`_ component. +Applications should use the interface (endpoint URI syntax and options) as +described in the bean component documentation but with the typed-actor schema. +Typed Actors must be added to a `Camel registry`_ for being accessible by the +typed-actor component. + +.. _typed-actor: http://github.com/jboner/akka/blob/master/akka-camel/src/main/scala/akka/camel/component/TypedActorComponent.scala +.. _bean: http://camel.apache.org/bean.html +.. _Camel registry: http://camel.apache.org/registry.html + + +.. _camel-typed-actors-using-spring: + +Using Spring +^^^^^^^^^^^^ + +The following example shows how to access typed actors in a Spring application +context. For adding typed actors to the application context and for starting +:ref:`camel-spring-applications` the :ref:`spring-module` module is used in the +following example. It offers a ```` element to define typed actor +factory beans and a ```` element to create and start a +CamelService. + +.. code-block:: xml + + + + + + + + + + + + + + + + + +SampleTypedActor is the typed actor interface and SampleTypedActorImpl in the +typed actor implementation class. + +**Scala** + +.. code-block:: scala + + package sample + + import akka.actor.TypedActor + + trait SampleTypedActor { + def foo(s: String): String + } + + class SampleTypedActorImpl extends TypedActor with SampleTypedActor { + def foo(s: String) = "hello %s" format s + } + +**Java** + +.. code-block:: java + + package sample; + + import akka.actor.TypedActor; + + public interface SampleTypedActor { + public String foo(String s); + } + + public class SampleTypedActorImpl extends TypedActor implements SampleTypedActor { + + public String foo(String s) { + return "hello " + s; + } + } + +The SampleRouteBuilder defines a custom route from the direct:test endpoint to +the sample typed actor using a typed-actor endpoint URI. + +**Scala** + +.. code-block:: scala + + package sample + + import org.apache.camel.builder.RouteBuilder + + class SampleRouteBuilder extends RouteBuilder { + def configure = { + // route to typed actor + from("direct:test").to("typed-actor:sample?method=foo") + } + } + +**Java** + +.. code-block:: java + + package sample; + + import org.apache.camel.builder.RouteBuilder; + + public class SampleRouteBuilder extends RouteBuilder { + public void configure() { + // route to typed actor + from("direct:test").to("typed-actor:sample?method=foo"); + } + } + +The typed-actor endpoint URI syntax is::: + + typed-actor:?method= + +where ```` is the id of the bean in the Spring application context and +```` is the name of the typed actor method to invoke. + +Usage of the custom route for sending a message to the typed actor is shown in +the following snippet. + +**Scala** + +.. code-block:: scala + + package sample + + import org.springframework.context.support.ClassPathXmlApplicationContext + import akka.camel.CamelContextManager + + // load Spring application context (starts CamelService) + val appctx = new ClassPathXmlApplicationContext("/context-standalone.xml") + + // access 'sample' typed actor via custom route + assert("hello akka" == CamelContextManager.mandatoryTemplate.requestBody("direct:test", "akka")) + + // close Spring application context (stops CamelService) + appctx.close + +**Java** + +.. code-block:: java + + package sample; + + import org.springframework.context.support.ClassPathXmlApplicationContext; + import akka.camel.CamelContextManager; + + // load Spring application context + ClassPathXmlApplicationContext appctx = new ClassPathXmlApplicationContext("/context-standalone.xml"); + + // access 'externally' registered typed actors with typed-actor component + assert("hello akka" == CamelContextManager.getMandatoryTemplate().requestBody("direct:test", "akka")); + + // close Spring application context (stops CamelService) + appctx.close(); + +The application uses a Camel `producer template`_ to access the typed actor via +the ``direct:test`` endpoint. + +.. _producer template: http://camel.apache.org/producertemplate.html + + +Without Spring +^^^^^^^^^^^^^^ + +Usage of :ref:`spring-module` for adding typed actors to the Camel registry and +starting a CamelService is optional. Setting up a Spring-less application for +accessing typed actors is shown in the next example. + +**Scala** + +.. code-block:: scala + + package sample + + import org.apache.camel.impl.{DefaultCamelContext, SimpleRegistry} + import akka.actor.TypedActor + import akka.camel.CamelContextManager + import akka.camel.CamelServiceManager._ + + // register typed actor + val registry = new SimpleRegistry + registry.put("sample", TypedActor.newInstance(classOf[SampleTypedActor], classOf[SampleTypedActorImpl])) + + // customize CamelContext + CamelContextManager.init(new DefaultCamelContext(registry)) + CamelContextManager.mandatoryContext.addRoutes(new SampleRouteBuilder) + + startCamelService + + // access 'sample' typed actor via custom route + assert("hello akka" == CamelContextManager.mandatoryTemplate.requestBody("direct:test", "akka")) + + stopCamelService + +**Java** + +.. code-block:: java + + package sample; + + // register typed actor + SimpleRegistry registry = new SimpleRegistry(); + registry.put("sample", TypedActor.newInstance(SampleTypedActor.class, SampleTypedActorImpl.class)); + + // customize CamelContext + CamelContextManager.init(new DefaultCamelContext(registry)); + CamelContextManager.getMandatoryContext().addRoutes(new SampleRouteBuilder()); + + startCamelService(); + + // access 'sample' typed actor via custom route + assert("hello akka" == CamelContextManager.getMandatoryTemplate().requestBody("direct:test", "akka")); + + stopCamelService(); + +Here, `SimpleRegistry`_, a java.util.Map based registry, is used to register +typed actors. The CamelService is started and stopped programmatically. + +.. _SimpleRegistry: https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/SimpleRegistry.java + + +.. _camel-intercepting-route-construction: + +Intercepting route construction +------------------------------- + +The previous section, :ref:`camel-components`, explained how to setup a route to +an (untyped) actor or typed actor manually. It was the application's +responsibility to define the route and add it to the current CamelContext. This +section explains a more conventient way to define custom routes: akka-camel is +still setting up the routes to consumer actors (and adds these routes to the +current CamelContext) but applications can define extensions to these routes. +Extensions can be defined with Camel's `Java DSL`_ or `Scala DSL`_. For example, +an extension could be a custom error handler that redelivers messages from an +endpoint to an actor's bounded mailbox when the mailbox was full. + +.. _Java DSL: http://camel.apache.org/dsl.html +.. _Scala DSL: http://camel.apache.org/scala-dsl.html + +The following examples demonstrate how to extend a route to a consumer actor for +handling exceptions thrown by that actor. To simplify the example, we configure +:ref:`camel-blocking-exchanges` which reports any exception, that is thrown by +receive, directly back to the Camel route. One could also report exceptions +asynchronously using a Failure reply (see also `this article`__) but we'll do it +differently here. + +__ http://krasserm.blogspot.com/2011/02/akka-consumer-actors-new-features-and.html + + +Actors (untyped) +^^^^^^^^^^^^^^^^ + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor + import akka.camel.Consumer + + import org.apache.camel.builder.Builder + import org.apache.camel.model.RouteDefinition + + class ErrorHandlingConsumer extends Actor with Consumer { + def endpointUri = "direct:error-handler-test" + + // Needed to propagate exception back to caller + override def blocking = true + + onRouteDefinition {rd: RouteDefinition => + // Catch any exception and handle it by returning the exception message as response + rd.onException(classOf[Exception]).handled(true).transform(Builder.exceptionMessage).end + } + + protected def receive = { + case msg: Message => throw new Exception("error: %s" format msg.body) + } + } + +**Java** + +.. code-block:: java + + import akka.camel.UntypedConsumerActor; + + import org.apache.camel.builder.Builder; + import org.apache.camel.model.ProcessorDefinition; + import org.apache.camel.model.RouteDefinition; + + public class SampleErrorHandlingConsumer extends UntypedConsumerActor { + + public String getEndpointUri() { + return "direct:error-handler-test"; + } + + // Needed to propagate exception back to caller + public boolean isBlocking() { + return true; + } + + public void preStart() { + onRouteDefinition(new RouteDefinitionHandler() { + public ProcessorDefinition onRouteDefinition(RouteDefinition rd) { + // Catch any exception and handle it by returning the exception message as response + return rd.onException(Exception.class).handled(true).transform(Builder.exceptionMessage()).end(); + } + }); + } + + public void onReceive(Object message) throws Exception { + Message msg = (Message)message; + String body = msg.getBodyAs(String.class); + throw new Exception(String.format("error: %s", body)); + } + + } + + + +For (untyped) actors, consumer route extensions are defined by calling the +onRouteDefinition method with a route definition handler. In Scala, this is a +function of type ``RouteDefinition => ProcessorDefinition[_]``, in Java it is an +instance of ``RouteDefinitionHandler`` which is defined as follows. + +.. code-block:: scala + + package akka.camel + + import org.apache.camel.model.RouteDefinition + import org.apache.camel.model.ProcessorDefinition + + trait RouteDefinitionHandler { + def onRouteDefinition(rd: RouteDefinition): ProcessorDefinition[_] + } + +The akka-camel module creates a RouteDefinition instance by calling +from(endpointUri) on a Camel RouteBuilder (where endpointUri is the endpoint URI +of the consumer actor) and passes that instance as argument to the route +definition handler \*). The route definition handler then extends the route and +returns a ProcessorDefinition (in the above example, the ProcessorDefinition +returned by the end method. See the `org.apache.camel.model`__ package for +details). After executing the route definition handler, akka-camel finally calls +a to(actor:uuid:actorUuid) on the returned ProcessorDefinition to complete the +route to the comsumer actor (where actorUuid is the uuid of the consumer actor). + +\*) Before passing the RouteDefinition instance to the route definition handler, +akka-camel may make some further modifications to it. + +__ https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ + + +Typed actors +^^^^^^^^^^^^ + +For typed consumer actors to define a route definition handler, they must +provide a RouteDefinitionHandler implementation class with the @consume +annotation. The implementation class must have a no-arg constructor. Here's an +example (in Java). + +.. code-block:: java + + import org.apache.camel.builder.Builder; + import org.apache.camel.model.ProcessorDefinition; + import org.apache.camel.model.RouteDefinition; + + public class SampleRouteDefinitionHandler implements RouteDefinitionHandler { + public ProcessorDefinition onRouteDefinition(RouteDefinition rd) { + return rd.onException(Exception.class).handled(true).transform(Builder.exceptionMessage()).end(); + } + } + +It can be used as follows. + +**Scala** + +.. code-block:: scala + + trait TestTypedConsumer { + @consume(value="direct:error-handler-test", routeDefinitionHandler=classOf[SampleRouteDefinitionHandler]) + def foo(s: String): String + } + + // implementation class omitted + +**Java** + +.. code-block:: java + + public interface SampleErrorHandlingTypedConsumer { + + @consume(value="direct:error-handler-test", routeDefinitionHandler=SampleRouteDefinitionHandler.class) + String foo(String s); + + } + + // implementation class omitted + + +.. _camel-examples: + +Examples +======== + +For all features described so far, there's running sample code in +`akka-sample-camel`_. The examples in `sample.camel.Boot`_ are started during +Kernel startup because this class has been added to the boot :ref:`configuration`. + +.. _akka-sample-camel: http://github.com/jboner/akka/tree/master/akka-samples/akka-sample-camel/ +.. _sample.camel.Boot: http://github.com/jboner/akka/blob/master/akka-samples/akka-sample-camel/src/main/scala/sample/camel/Boot.scala + +.. code-block:: none + + akka { + ... + boot = ["sample.camel.Boot", ...] + ... + } + +If you don't want to have these examples started during Kernel startup, delete +it from the :ref:`configuration`. Other examples are standalone applications (i.e. classes with a +main method) that can be started from `sbt`_. + +.. _sbt: http://code.google.com/p/simple-build-tool/ + +.. code-block:: none + + $ sbt + [info] Building project akka 2.0-SNAPSHOT against Scala 2.9.0 + [info] using AkkaModulesParentProject with sbt 0.7.7 and Scala 2.7.7 + > project akka-sample-camel + Set current project to akka-sample-camel 2.0-SNAPSHOT + > run + ... + Multiple main classes detected, select one to run: + + [1] sample.camel.ClientApplication + [2] sample.camel.ServerApplication + [3] sample.camel.StandaloneSpringApplication + [4] sample.camel.StandaloneApplication + [5] sample.camel.StandaloneFileApplication + [6] sample.camel.StandaloneJmsApplication + + +Some of the examples in `akka-sample-camel`_ are described in more detail in the +following subsections. + + +.. _camel-async-example: + +Asynchronous routing and transformation example +----------------------------------------------- + +This example demonstrates how to implement consumer and producer actors that +support :ref:`camel-asynchronous-routing` with their Camel endpoints. The sample +application transforms the content of the Akka homepage, http://akka.io, by +replacing every occurrence of *Akka* with *AKKA*. After starting +the :ref:`microkernel`, direct the browser to http://localhost:8875 and the +transformed Akka homepage should be displayed. Please note that this example +will probably not work if you're behind an HTTP proxy. + +The following figure gives an overview how the example actors interact with +external systems and with each other. A browser sends a GET request to +http://localhost:8875 which is the published endpoint of the ``HttpConsumer`` +actor. The ``HttpConsumer`` actor forwards the requests to the ``HttpProducer`` +actor which retrieves the Akka homepage from http://akka.io. The retrieved HTML +is then forwarded to the ``HttpTransformer`` actor which replaces all occurences +of *Akka* with *AKKA*. The transformation result is sent back the HttpConsumer +which finally returns it to the browser. + +.. image:: camel-async-interact.png + +Implementing the example actor classes and wiring them together is rather easy +as shown in the following snippet (see also `sample.camel.Boot`_). + +.. code-block:: scala + + import org.apache.camel.Exchange + import akka.actor.Actor._ + import akka.actor.{Actor, ActorRef} + import akka.camel.{Producer, Message, Consumer} + + class HttpConsumer(producer: ActorRef) extends Actor with Consumer { + def endpointUri = "jetty:http://0.0.0.0:8875/" + + protected def receive = { + case msg => producer forward msg + } + } + + class HttpProducer(transformer: ActorRef) extends Actor with Producer { + def endpointUri = "jetty://http://akka.io/?bridgeEndpoint=true" + + override protected def receiveBeforeProduce = { + // only keep Exchange.HTTP_PATH message header (which needed by bridge endpoint) + case msg: Message => msg.setHeaders(msg.headers(Set(Exchange.HTTP_PATH))) + } + + override protected def receiveAfterProduce = { + // do not reply but forward result to transformer + case msg => transformer forward msg + } + } + + class HttpTransformer extends Actor { + protected def receive = { + case msg: Message => self.reply(msg.transformBody {body: String => body replaceAll ("Akka ", "AKKA ")}) + case msg: Failure => self.reply(msg) + } + } + + // Wire and start the example actors + val httpTransformer = actorOf(Props(new HttpTransformer)) + val httpProducer = actorOf(Props(new HttpProducer(httpTransformer))) + val httpConsumer = actorOf(Props(new HttpConsumer(httpProducer))) + +The `jetty endpoints`_ of HttpConsumer and HttpProducer support asynchronous +in-out message exchanges and do not allocate threads for the full duration of +the exchange. This is achieved by using `Jetty continuations`_ on the +consumer-side and by using `Jetty's asynchronous HTTP client`_ on the producer +side. The following high-level sequence diagram illustrates that. + +.. _jetty endpoints: http://camel.apache.org/jetty.html +.. _Jetty continuations: http://wiki.eclipse.org/Jetty/Feature/Continuations +.. _Jetty's asynchronous HTTP client: http://wiki.eclipse.org/Jetty/Tutorial/HttpClient + +.. image:: camel-async-sequence.png + + +Custom Camel route example +-------------------------- + +This section also demonstrates the combined usage of a ``Producer`` and a +``Consumer`` actor as well as the inclusion of a custom Camel route. The +following figure gives an overview. + +.. image:: camel-custom-route.png + +* A consumer actor receives a message from an HTTP client + +* It forwards the message to another actor that transforms the message (encloses + the original message into hyphens) + +* The transformer actor forwards the transformed message to a producer actor + +* The producer actor sends the message to a custom Camel route beginning at the + ``direct:welcome`` endpoint + +* A processor (transformer) in the custom Camel route prepends "Welcome" to the + original message and creates a result message + +* The producer actor sends the result back to the consumer actor which returns + it to the HTTP client + + +The example is part of `sample.camel.Boot`_. The consumer, transformer and +producer actor implementations are as follows. + +.. code-block:: scala + + package sample.camel + + import akka.actor.{Actor, ActorRef} + import akka.camel.{Message, Consumer} + + class Consumer3(transformer: ActorRef) extends Actor with Consumer { + def endpointUri = "jetty:http://0.0.0.0:8877/camel/welcome" + + def receive = { + // Forward a string representation of the message body to transformer + case msg: Message => transformer.forward(msg.setBodyAs[String]) + } + } + + class Transformer(producer: ActorRef) extends Actor { + protected def receive = { + // example: transform message body "foo" to "- foo -" and forward result to producer + case msg: Message => producer.forward(msg.transformBody((body: String) => "- %s -" format body)) + } + } + + class Producer1 extends Actor with Producer { + def endpointUri = "direct:welcome" + } + +The producer actor knows where to reply the message to because the consumer and +transformer actors have forwarded the original sender reference as well. The +application configuration and the route starting from direct:welcome are as +follows. + +.. code-block:: scala + + package sample.camel + + import org.apache.camel.builder.RouteBuilder + import org.apache.camel.{Exchange, Processor} + + import akka.actor.Actor._ + import akka.camel.CamelContextManager + + class Boot { + CamelContextManager.init() + CamelContextManager.mandatoryContext.addRoutes(new CustomRouteBuilder) + + val producer = actorOf(Props[Producer1]) + val mediator = actorOf(Props(new Transformer(producer))) + val consumer = actorOf(Props(new Consumer3(mediator))) + } + + class CustomRouteBuilder extends RouteBuilder { + def configure { + from("direct:welcome").process(new Processor() { + def process(exchange: Exchange) { + // Create a 'welcome' message from the input message + exchange.getOut.setBody("Welcome %s" format exchange.getIn.getBody) + } + }) + } + } + +To run the example, start the :ref:`microkernel` and POST a message to +``http://localhost:8877/camel/welcome``. + +.. code-block:: none + + curl -H "Content-Type: text/plain" -d "Anke" http://localhost:8877/camel/welcome + +The response should be: + +.. code-block:: none + + Welcome - Anke - + + +Publish-subcribe example +------------------------ + +JMS +^^^ + +This section demonstrates how akka-camel can be used to implement +publish/subscribe for actors. The following figure sketches an example for +JMS-based publish/subscribe. + +.. image:: camel-pubsub.png + +A consumer actor receives a message from an HTTP client. It sends the message to +a JMS producer actor (publisher). The JMS producer actor publishes the message +to a JMS topic. Two other actors that subscribed to that topic both receive the +message. The actor classes used in this example are shown in the following +snippet. + +.. code-block:: scala + + package sample.camel + + import akka.actor.{Actor, ActorRef} + import akka.camel.{Producer, Message, Consumer} + + class Subscriber(name:String, uri: String) extends Actor with Consumer { + def endpointUri = uri + + protected def receive = { + case msg: Message => println("%s received: %s" format (name, msg.body)) + } + } + + class Publisher(name: String, uri: String) extends Actor with Producer { + self.id = name + + def endpointUri = uri + + // one-way communication with JMS + override def oneway = true + } + + class PublisherBridge(uri: String, publisher: ActorRef) extends Actor with Consumer { + def endpointUri = uri + + protected def receive = { + case msg: Message => { + publisher ! msg.bodyAs[String] + self.reply("message published") + } + } + } + +Wiring these actors to implement the above example is as simple as + +.. code-block:: scala + + package sample.camel + + import org.apache.camel.impl.DefaultCamelContext + import org.apache.camel.spring.spi.ApplicationContextRegistry + import org.springframework.context.support.ClassPathXmlApplicationContext + + import akka.actor.Actor._ + import akka.camel.CamelContextManager + + class Boot { + // Create CamelContext with Spring-based registry and custom route builder + val context = new ClassPathXmlApplicationContext("/context-jms.xml", getClass) + val registry = new ApplicationContextRegistry(context) + CamelContextManager.init(new DefaultCamelContext(registry)) + + // Setup publish/subscribe example + val jmsUri = "jms:topic:test" + val jmsSubscriber1 = actorOf(Props(new Subscriber("jms-subscriber-1", jmsUri))) + val jmsSubscriber2 = actorOf(Props(new Subscriber("jms-subscriber-2", jmsUri))) + val jmsPublisher = actorOf(Props(new Publisher("jms-publisher", jmsUri))) + + val jmsPublisherBridge = actorOf(Props(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/jms", jmsPublisher))) + } + +To publish messages to subscribers one could of course also use the JMS API +directly; there's no need to do that over a JMS producer actor as in this +example. For the example to work, Camel's `jms`_ component needs to be +configured with a JMS connection factory which is done in a Spring application +context XML file (context-jms.xml). + +.. _jms: http://camel.apache.org/jms.html + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + +To run the example, start the :ref:`microkernel` and POST a +message to ``http://localhost:8877/camel/pub/jms``. + +.. code-block:: none + + curl -H "Content-Type: text/plain" -d "Happy hAkking" http://localhost:8877/camel/pub/jms + +The HTTP response body should be + +.. code-block:: none + + message published + +On the console, where you started the Akka Kernel, you should see something like + +.. code-block:: none + + ... + INF [20100622-11:49:57.688] camel: jms-subscriber-2 received: Happy hAkking + INF [20100622-11:49:57.688] camel: jms-subscriber-1 received: Happy hAkking + + +Cometd +^^^^^^ + +Publish/subscribe with `CometD`_ is equally easy using `Camel's cometd +component`_. + +.. _CometD: http://cometd.org/ +.. _Camel's cometd component: http://camel.apache.org/cometd.html + +.. image:: camel-pubsub2.png + +All actor classes from the JMS example can re-used, only the endpoint URIs need +to be changed. + +.. code-block:: scala + + package sample.camel + + import org.apache.camel.impl.DefaultCamelContext + import org.apache.camel.spring.spi.ApplicationContextRegistry + import org.springframework.context.support.ClassPathXmlApplicationContext + + import akka.actor.Actor._ + import akka.camel.CamelContextManager + + class Boot { + // ... + + // Setup publish/subscribe example + val cometdUri = "cometd://localhost:8111/test/abc?resourceBase=target" + val cometdSubscriber = actorOf(Props(new Subscriber("cometd-subscriber", cometdUri))) + val cometdPublisher = actorOf(Props(new Publisher("cometd-publisher", cometdUri))) + + val cometdPublisherBridge = actorOf(Props(new PublisherBridge("jetty:http://0.0.0.0:8877/camel/pub/cometd", cometdPublisher))) + } + + +Quartz Scheduler Example +------------------------ + +Here is an example showing how simple is to implement a cron-style scheduler by +using the Camel Quartz component in Akka. + +The following example creates a "timer" actor which fires a message every 2 +seconds: + +.. code-block:: scala + + package com.dimingo.akka + + import akka.actor.Actor + import akka.actor.Actor.actorOf + + import akka.camel.{Consumer, Message} + import akka.camel.CamelServiceManager._ + + class MyQuartzActor extends Actor with Consumer { + + def endpointUri = "quartz://example?cron=0/2+*+*+*+*+?" + + def receive = { + + case msg => println("==============> received %s " format msg) + + } // end receive + + } // end MyQuartzActor + + object MyQuartzActor { + + def main(str: Array[String]) { + + // start the Camel service + startCamelService + + // create and start a quartz actor + val myActor = actorOf(Props[MyQuartzActor]) + + } // end main + + } // end MyQuartzActor + +The full working example is available for download here: +http://www.dimingo.com/akka/examples/example-akka-quartz.tar.gz + +You can launch it using the maven command: + +.. code-block:: none + + $ mvn scala:run -DmainClass=com.dimingo.akka.MyQuartzActor + +For more information about the Camel Quartz component, see here: +http://camel.apache.org/quartz.html diff --git a/akka-docs/project/migration-guide-0.10.x-1.0.x.rst b/akka-docs/project/migration-guide-0.10.x-1.0.x.rst new file mode 100644 index 0000000000..6352e63061 --- /dev/null +++ b/akka-docs/project/migration-guide-0.10.x-1.0.x.rst @@ -0,0 +1,447 @@ +Migration Guide 0.10.x to 1.0.x +==================================== + +Akka & Akka Modules separated into two different repositories and distributions +------------------------------------------------------------------------------- + +Akka is split up into two different parts: +* Akka - Reflects all the sections under 'Scala API' and 'Java API' in the navigation bar. +* Akka Modules - Reflects all the sections under 'Add-on modules' in the navigation bar. + +Download the release you need (Akka core or Akka Modules) from ``_ and unzip it. + +---- + +Changed Akka URI +---------------- + +http://akkasource.org changed to http://akka.io + +Reflects XSDs, Maven repositories, ScalaDoc etc. + +---- + +Removed 'se.scalablesolutions' prefix +------------------------------------- + +We have removed some boilerplate by shortening the Akka package from +**se.scalablesolutions.akka** to just **akka** so just do a search-replace in your project, +we apologize for the inconvenience, but we did it for our users. + +---- + +Akka-core is no more +-------------------- + +Akka-core has been split into akka-actor, akka-stm, akka-typed-actor & akka-remote this means that you need to update any deps you have on akka-core. + +---- + +Config +------ + +Turning on/off modules +^^^^^^^^^^^^^^^^^^^^^^ + +All the 'service = on' elements for turning modules on and off have been replaced by a top-level list of the enabled services. + +Services available for turning on/off are: +* "remote" +* "http" +* "camel" + +**All** services are **OFF** by default. Enable the ones you are using. + +.. code-block:: ruby + + akka { + enabled-modules = [] # Comma separated list of the enabled modules. Options: ["remote", "camel", "http"] + } + +Renames +^^^^^^^ + +* 'rest' section - has been renamed to 'http' to align with the module name 'akka-http'. +* 'storage' section - has been renamed to 'persistence' to align with the module name 'akka-persistence'. + +.. code-block:: ruby + + akka { + http { + .. + } + + persistence { + .. + } + } + +---- + +Important changes from RC2-RC3 +------------------------------ + +**akka.config.SupervisionSupervise** + +**Scala** + +.. code-block:: scala + + def apply(actorRef: ActorRef, lifeCycle: LifeCycle, registerAsRemoteService: Boolean = false) + +- boolean instead of remoteAddress, registers that actor with it's id as service name on the local server + +**akka.actor.Actors now is the API for Java to interact with Actors, Remoting and ActorRegistry:** + +**Java** + +.. code-block:: java + + import static akka.actor.Actors.*; // <-- The important part + + actorOf(); + remote().actorOf(); + registry().actorsFor("foo"); + +***akka.actor.Actor now is the API for Scala to interact with Actors, Remoting and ActorRegistry:*** + +**Scala** + +.. code-block:: scala + + import akka.actor.Actor._ // <-- The important part + + actorOf().method + remote.actorOf() + registry.actorsFor("foo") + +**object UntypedActor has been deleted and replaced with akka.actor.Actors/akka.actor.Actor (Java/Scala)** + +- UntypedActor.actorOf -> Actors.actorOf (Java) or Actor.actorOf (Scala) + +**object ActorRegistry has been deleted and replaced with akka.actor.Actors.registry()/akka.actor.Actor.registry (Java/Scala)** + +- ActorRegistry. -> Actors.registry(). (Java) or Actor.registry. (Scala) + +**object RemoteClient has been deleted and replaced with akka.actor.Actors.remote()/akka.actor.Actor.remote (Java/Scala)** + +- RemoteClient -> Actors.remote() (Java) or Actor.remote (Scala) + +**object RemoteServer has been deleted and replaced with akka.actor.Actors.remote()/akka.actor.Actor.remote (Java/Scala)** + +- RemoteServer - deleted -> Actors.remote() (Java) or Actor.remote (Scala) + +**classes RemoteActor, RemoteUntypedActor and RemoteUntypedConsumerActors has been deleted and replaced with akka.actor.Actors.remote().actorOf(x, host port)/akka.actor.Actor.remote.actorOf(x, host, port)** + +- RemoteActor, RemoteUntypedActor - deleted, use: remote().actorOf(YourActor.class, host, port) (Java) or remote.actorOf(Props[YourActor](host, port) + +**Remoted spring-actors now default to spring id as service-name, use "service-name" attribute on "remote"-tag to override** + +**Listeners for RemoteServer and RemoteClient** are now registered on Actors.remote().addListener (Java) or Actor.remote.addListener (Scala), this means that all listeners get all remote events, both remote server evens and remote client events, **so adjust your code accordingly.** + +**ActorRef.startLinkRemote has been removed since one specified on creation wether the actor is client-managed or not.** + +Important change from RC3 to RC4 +-------------------------------- + +The Akka-Spring namespace has changed from akkasource.org and scalablesolutions.se to http://akka.io/schema and http://akka.io/akka-.xsd + +Module akka-actor +----------------- + +The Actor.init callback has been renamed to "preStart" to align with the general callback naming and is more clear about when it's called. + +The Actor.shutdown callback has been renamed to "postStop" to align with the general callback naming and is more clear about when it's called. + +The Actor.initTransactionalState callback has been removed, logic should be moved to preStart and be wrapped in an atomic block + +**se.scalablesolutions.akka.config.ScalaConfig** and **se.scalablesolutions.akka.config.JavaConfig** have been merged into **akka.config.Supervision** + +**RemoteAddress** has moved from **se.scalablesolutions.akka.config.ScalaConfig** to **akka.config** + +The ActorRef.lifeCycle has changed signature from Option[LifeCycle] to LifeCycle, this means you need to change code that looks like this: +**self.lifeCycle = Some(LifeCycle(Permanent))** to **self.lifeCycle = Permanent** + +The equivalent to **self.lifeCycle = None** is **self.lifeCycle = UndefinedLifeCycle** +**LifeCycle(Permanent)** becomes **Permanent** +**new LifeCycle(permanent())** becomes **permanent()** (need to do: import static se.scalablesolutions.akka.config.Supervision.*; first) + +**JavaConfig.Component** and **ScalaConfig.Component** have been consolidated and renamed as **Supervision.SuperviseTypedActor** + +**self.trapExit** has been moved into the FaultHandlingStrategy, and **ActorRef.faultHandler** has switched type from Option[FaultHandlingStrategy] +to FaultHandlingStrategy: + +**Scala** + +.. code-block:: scala + + import akka.config.Supervision._ + + self.faultHandler = OneForOneStrategy(List(classOf[Exception]), 3, 5000) + +**Java** + +.. code-block:: java + + import static akka.Supervision.*; + + getContext().setFaultHandler(new OneForOneStrategy(new Class[] { Exception.class },50,1000)) + +**RestartStrategy, AllForOne, OneForOne** have been replaced with **AllForOneStrategy** and **OneForOneStrategy** in **se.scalablesolutions.akka.config.Supervision** + +**Scala** + +.. code-block:: scala + + import akka.config.Supervision._ + SupervisorConfig( + OneForOneStrategy(List(classOf[Exception]), 3, 5000), + Supervise(pingpong1,Permanent) :: Nil + ) + +**Java** + +.. code-block:: java + + import static akka.Supervision.*; + + new SupervisorConfig( + new OneForOneStrategy(new Class[] { Exception.class },50,1000), + new Server[] { new Supervise(pingpong1, permanent()) } + ) + +***We have removed the following factory methods:*** + +**Actor.actor { case foo => bar }** +**Actor.transactor { case foo => bar }** +**Actor.temporaryActor { case foo => bar }** +**Actor.init {} receive { case foo => bar }** + +They started the actor and no config was possible, it was inconsistent and irreparable. + +replace with your own factories, or: + +**Scala** + +.. code-block:: scala + + actorOf( new Actor { def receive = { case foo => bar } } ).start + actorOf( new Actor { self.lifeCycle = Temporary; def receive = { case foo => bar } } ).start + +ReceiveTimeout is now rescheduled after every message, before there was only an initial timeout. +To stop rescheduling of ReceiveTimeout, set **receiveTimeout = None** + +HotSwap +------- + +HotSwap does no longer use behavior stacking by default, but that is an option to both "become" and HotSwap. + +HotSwap now takes for Scala a Function from ActorRef to a Receive, the ActorRef passed in is the reference to self, so you can do self.reply() etc. + +---- + +Module akka-stm +--------------- + +The STM stuff is now in its own module. This means that there is no support for transactions or transactors in akka-actor. + +Local and global +^^^^^^^^^^^^^^^^ + +The **local/global** distinction has been dropped. This means that if the following general import was being used: + +**Scala** + +.. code-block:: scala + + import akka.stm.local._ + +this is now just: + +**Scala** + +.. code-block:: scala + + import akka.stm._ + +Coordinated is the new global +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is a new explicit mechanism for coordinated transactions. See the `Scala Transactors `_ and `Java Transactors `_ documentation for more information. Coordinated transactions and transactors are found in the ``akka.transactor`` package now. The usage of transactors has changed. + +Agents +^^^^^^ + +Agent is now in the akka-stm module and has moved to the ``akka.agent`` package. The implementation has been reworked and is now closer to Clojure agents. There is not much difference in general usage, the main changes involve interaction with the STM. + +While updates to Agents are asynchronous, the state of an Agent is always immediately available for reading by any thread. Agents are integrated with the STM - any dispatches made in a transaction are held until that transaction commits, and are discarded if it is retried or aborted. There is a new ``sendOff`` method for long-running or blocking update functions. + +---- + +Module akka-camel +----------------- + +Access to the CamelService managed by CamelServiceManager has changed: + +* Method service renamed to mandatoryService (Scala) +* Method service now returns Option[CamelService] (Scala) +* Introduced method getMandatoryService() (Java) +* Introduced method getService() (Java) + +**Scala** + +.. code-block:: scala + + import se.scalablesolutions.akka.camel.CamelServiceManager._ + import se.scalablesolutions.akka.camel.CamelService + + val o: Option[CamelService] = service + val s: CamelService = mandatoryService + +**Java** + +.. code-block:: java + + import se.scalablesolutions.akka.camel.CamelService; + import se.scalablesolutions.akka.japi.Option; + import static se.scalablesolutions.akka.camel.CamelServiceManager.*; + + Option o = getService(); + CamelService s = getMandatoryService(); + +Access to the CamelContext and ProducerTemplate managed by CamelContextManager has changed: + +* Method context renamed to mandatoryContext (Scala) +* Method template renamed to mandatoryTemplate (Scala) +* Method service now returns Option[CamelContext] (Scala) +* Method template now returns Option[ProducerTemplate] (Scala) +* Introduced method getMandatoryContext() (Java) +* Introduced method getContext() (Java) +* Introduced method getMandatoryTemplate() (Java) +* Introduced method getTemplate() (Java) + +**Scala** + +.. code-block:: scala + + import org.apache.camel.CamelContext + import org.apache.camel.ProducerTemplate + + import se.scalablesolutions.akka.camel.CamelContextManager._ + + val co: Option[CamelContext] = context + val to: Option[ProducerTemplate] = template + + val c: CamelContext = mandatoryContext + val t: ProducerTemplate = mandatoryTemplate + +**Java** + +.. code-block:: java + + import org.apache.camel.CamelContext; + import org.apache.camel.ProducerTemplate; + + import se.scalablesolutions.akka.japi.Option; + import static se.scalablesolutions.akka.camel.CamelContextManager.*; + + Option co = getContext(); + Option to = getTemplate(); + + CamelContext c = getMandatoryContext(); + ProducerTemplate t = getMandatoryTemplate(); + +The following methods have been renamed on class se.scalablesolutions.akka.camel.Message: + +* bodyAs(Class) has been renamed to getBodyAs(Class) +* headerAs(String, Class) has been renamed to getHeaderAs(String, Class) + +The API for waiting for consumer endpoint activation and de-activation has been changed + +* CamelService.expectEndpointActivationCount has been removed and replaced by CamelService.awaitEndpointActivation +* CamelService.expectEndpointDeactivationCount has been removed and replaced by CamelService.awaitEndpointDeactivation + +**Scala** + +.. code-block:: scala + + import se.scalablesolutions.akka.actor.Actor + import se.scalablesolutions.akka.camel.CamelServiceManager._ + + val s = startCamelService + val actor = Actor.actorOf(Props[SampleConsumer] + + // wait for 1 consumer being activated + s.awaitEndpointActivation(1) { + actor.start + } + + // wait for 1 consumer being de-activated + s.awaitEndpointDeactivation(1) { + actor.stop + } + + s.stop + +**Java** + +.. code-block:: java + + import java.util.concurrent.TimeUnit; + import se.scalablesolutions.akka.actor.ActorRef; + import se.scalablesolutions.akka.actor.Actors; + import se.scalablesolutions.akka.camel.CamelService; + import se.scalablesolutions.akka.japi.SideEffect; + import static se.scalablesolutions.akka.camel.CamelServiceManager.*; + + CamelService s = startCamelService(); + final ActorRef actor = Actors.actorOf(SampleUntypedConsumer.class); + + // wait for 1 consumer being activated + s.awaitEndpointActivation(1, new SideEffect() { + public void apply() { + actor.start(); + } + }); + + // wait for 1 consumer being de-activated + s.awaitEndpointDeactivation(1, new SideEffect() { + public void apply() { + actor.stop(); + } + }); + + s.stop(); + +Module Akka-Http +---------------- + +Atmosphere support has been removed. If you were using akka.comet.AkkaServlet for Jersey support only, +you can switch that to: akka.http.AkkaRestServlet and it should work just like before. + +Atmosphere has been removed because we have a new async http support in the form of Akka Mist, a very thin bridge +between Servlet3.0/JettyContinuations and Actors, enabling Http-as-messages, read more about it here: +http://doc.akka.io/http#Mist%20-%20Lightweight%20Asynchronous%20HTTP + +If you really need Atmosphere support, you can add it yourself by following the steps listed at the start of: +http://doc.akka.io/comet + +Module akka-spring +------------------ + +The Akka XML schema URI has changed to http://akka.io/schema/akka + +.. code-block:: xml + + + + + + diff --git a/akka-docs/project/migration-guide-0.8.x-0.9.x.rst b/akka-docs/project/migration-guide-0.8.x-0.9.x.rst new file mode 100644 index 0000000000..868879a5b0 --- /dev/null +++ b/akka-docs/project/migration-guide-0.8.x-0.9.x.rst @@ -0,0 +1,172 @@ +Migration Guide 0.8.x to 0.9.x +============================== + +**This document describes between the 0.8.x and the 0.9 release.** + +Background for the new ActorRef +------------------------------- + +In the work towards 0.9 release we have now done a major change to how Actors are created. In short we have separated identity and value, created an 'ActorRef' that holds the actual Actor instance. This allows us to do many great things such as for example: + +* Create serializable, immutable, network-aware Actor references that can be freely shared across the network. They "remember" their origin and will always work as expected. +* Not only kill and restart the same supervised Actor instance when it has crashed (as we do now), but dereference it, throw it away and make it eligible for garbage collection. +* etc. much more + +These work very much like the 'PID' (process id) in Erlang. + +These changes means that there is no difference in defining Actors. You still use the old Actor trait, all methods are there etc. But you can't just new this Actor up and send messages to it since all its public API methods are gone. They now reside in a new class; 'ActorRef' and use need to use instances of this class to interact with the Actor (sending messages etc.). + +Here is a short migration guide with the things that you have to change. It is a big conceptual change but in practice you don't have to change much. + + + +Creating Actors with default constructor +---------------------------------------- + +From: + +.. code-block:: scala + + val a = new MyActor + a ! msg + +To: + +.. code-block:: scala + + import Actor._ + val a = actorOf(Props[MyActor] + a ! msg + +You can also start it in the same statement: + +.. code-block:: scala + + val a = actorOf(Props[MyActor] + +Creating Actors with non-default constructor +-------------------------------------------- + +From: + +.. code-block:: scala + + val a = new MyActor(..) + a ! msg + +To: + +.. code-block:: scala + + import Actor._ + val a = actorOf(Props(new MyActor(..)) + a ! msg + +Use of 'self' ActorRef API +-------------------------- + +Where you have used 'this' to refer to the Actor from within itself now use 'self': + +.. code-block:: scala + + self ! MessageToMe + +Now the Actor trait only has the callbacks you can implement: +* receive +* postRestart/preRestart +* init/shutdown + +It has no state at all. + +All API has been moved to ActorRef. The Actor is given its ActorRef through the 'self' member variable. +Here you find functions like: +* !, !!, !!! and forward +* link, unlink, startLink, spawnLink etc +* makeTransactional, makeRemote etc. +* start, stop +* etc. + +Here you also find fields like +* dispatcher = ... +* id = ... +* lifeCycle = ... +* faultHandler = ... +* trapExit = ... +* etc. + +This means that to use them you have to prefix them with 'self', like this: + +.. code-block:: scala + + self ! Message + +However, for convenience you can import these functions and fields like below, which will allow you do drop the 'self' prefix: + +.. code-block:: scala + + class MyActor extends Actor { + import self._ + id = ... + dispatcher = ... + spawnLink[OtherActor] + ... + } + +Serialization +------------- + +If you want to serialize it yourself, here is how to do it: + +.. code-block:: scala + + val actorRef1 = actorOf(Props[MyActor] + + val bytes = actorRef1.toBinary + + val actorRef2 = ActorRef.fromBinary(bytes) + +If you are also using Protobuf then you can use the methods that work with Protobuf's Messages directly. + +.. code-block:: scala + + val actorRef1 = actorOf(Props[MyActor] + + val protobufMessage = actorRef1.toProtocol + + val actorRef2 = ActorRef.fromProtocol(protobufMessage) + +Camel +----- + +Some methods of the se.scalablesolutions.akka.camel.Message class have been deprecated in 0.9. These are + +.. code-block:: scala + + package se.scalablesolutions.akka.camel + + case class Message(...) { + // ... + @deprecated def bodyAs[T](clazz: Class[T]): T + @deprecated def setBodyAs[T](clazz: Class[T]): Message + // ... + } + +They will be removed in 1.0. Instead use + +.. code-block:: scala + + package se.scalablesolutions.akka.camel + + case class Message(...) { + // ... + def bodyAs[T](implicit m: Manifest[T]): T = + def setBodyAs[T](implicit m: Manifest[T]): Message + // ... + } + +Usage example: +.. code-block:: scala + + val m = Message(1.4) + val b = m.bodyAs[String] + diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index eb4649e2c8..618d2618c9 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -54,7 +54,7 @@ Creating Actors with default constructor ---------------------------------------- .. includecode:: code/ActorDocSpec.scala - :include: imports2,system-actorOf +:include: imports2,system-actorOf The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to the ``Actor`` instance which you can use to interact with the ``Actor``. The @@ -73,7 +73,7 @@ a top level actor, that is supervised by the system (internal guardian actor). .. includecode:: code/ActorDocSpec.scala#context-actorOf Actors are automatically started asynchronously when created. -When you create the ``Actor`` then it will automatically call the ``preStart`` +When you create the ``Actor`` then it will automatically call the ``preStart`` callback method on the ``Actor`` trait. This is an excellent place to add initialization code for the actor. @@ -87,7 +87,7 @@ Creating Actors with non-default constructor -------------------------------------------- If your Actor has a constructor that takes parameters then you can't create it -using ``actorOf[TYPE]``. Instead you can use a variant of ``actorOf`` that takes +using ``actorOf(Props[TYPE])``. Instead you can use a variant of ``actorOf`` that takes a call-by-name block in which you can create the Actor in any way you like. Here is an example: @@ -98,7 +98,7 @@ Here is an example: Creating Actors with Props -------------------------- -``Props`` is a configuration object to specify additional things for the actor to +``Props`` is a configuration object to specify additional things for the actor to be created, such as the ``MessageDispatcher``. .. includecode:: code/ActorDocSpec.scala#creating-props @@ -128,7 +128,7 @@ Actor API The :class:`Actor` trait defines only one abstract method, the above mentioned :meth:`receive`, which implements the behavior of the actor. -If the current actor behavior does not match a received message, :meth:`unhandled` +If the current actor behavior does not match a received message, :meth:`unhandled` is called, which by default throws an :class:`UnhandledMessageException`. In addition, it offers: @@ -145,7 +145,7 @@ In addition, it offers: You can import the members in the :obj:`context` to avoid prefixing access with ``context.`` -.. includecode:: code/ActorDocSpec.scala#import-context +.. includecode:: code/ActorDocSpec.scala#import-context The remaining visible methods are user-overridable life-cycle hooks which are described in the following:: @@ -195,7 +195,7 @@ processing a message. This restart involves the hooks mentioned above: An actor restart replaces only the actual actor object; the contents of the mailbox and the hotswap stack are unaffected by the restart, so processing of -messages will resume after the :meth:`postRestart` hook returns. The message +messages will resume after the :meth:`postRestart` hook returns. The message that triggered the exception will not be received again. Any message sent to an actor while it is being restarted will be queued to its mailbox as usual. @@ -205,9 +205,9 @@ Stop Hook After stopping an actor, its :meth:`postStop` hook is called, which may be used e.g. for deregistering this actor from other services. This hook is guaranteed -to run after message queuing has been disabled for this actor, i.e. messages -sent to a stopped actor will be redirected to the :obj:`deadLetters` of the -:obj:`ActorSystem`. +to run after message queuing has been disabled for this actor, i.e. messages +sent to a stopped actor will be redirected to the :obj:`deadLetters` of the +:obj:`ActorSystem`. Identifying Actors @@ -267,7 +267,7 @@ implicitly passed along with the message and available to the receiving Actor in its ``sender: ActorRef`` member field. The target actor can use this to reply to the original sender, by using ``sender ! replyMsg``. -If invoked from an instance that is **not** an Actor the sender will be +If invoked from an instance that is **not** an Actor the sender will be :obj:`deadLetters` actor reference by default. Ask: Send-And-Receive-Future @@ -281,11 +281,11 @@ will immediately return a :class:`Future`: val future = actor ? "hello" The receiving actor should reply to this message, which will complete the -future with the reply message as value; ``sender ! result``. +future with the reply message as value; ``sender ! result``. -To complete the future with an exception you need send a Failure message to the sender. -This is not done automatically when an actor throws an exception while processing a -message. +To complete the future with an exception you need send a Failure message to the sender. +This is not done automatically when an actor throws an exception while processing a +message. .. includecode:: code/ActorDocSpec.scala#reply-exception @@ -296,7 +296,7 @@ which is taken from one of the following locations in order of precedence: #. implicit argument of type :class:`akka.actor.Timeout`, e.g. :: - + import akka.actor.Timeout import akka.util.duration._ @@ -306,16 +306,16 @@ which is taken from one of the following locations in order of precedence: See :ref:`futures-scala` for more information on how to await or query a future. -The ``onComplete``, ``onResult``, or ``onTimeout`` methods of the ``Future`` can be -used to register a callback to get a notification when the Future completes. +The ``onComplete``, ``onResult``, or ``onTimeout`` methods of the ``Future`` can be +used to register a callback to get a notification when the Future completes. Gives you a way to avoid blocking. .. warning:: When using future callbacks, inside actors you need to carefully avoid closing over - the containing actor’s reference, i.e. do not call methods or access mutable state - on the enclosing actor from within the callback. This would break the actor - encapsulation and may introduce synchronization bugs and race conditions because + the containing actor’s reference, i.e. do not call methods or access mutable state + on the enclosing actor from within the callback. This would break the actor + encapsulation and may introduce synchronization bugs and race conditions because the callback will be scheduled concurrently to the enclosing actor. Unfortunately there is not yet a way to detect these illegal accesses at compile time. See also: :ref:`jmm-shared-state` @@ -403,17 +403,17 @@ object. Stopping actors =============== -Actors are stopped by invoking the ``stop`` method of the ``ActorRef``. +Actors are stopped by invoking the ``stop`` method of the ``ActorRef``. The actual termination of the actor is performed asynchronously, i.e. -``stop`` may return before the actor is stopped. +``stop`` may return before the actor is stopped. .. code-block:: scala actor.stop() -Processing of the current message, if any, will continue before the actor is stopped, +Processing of the current message, if any, will continue before the actor is stopped, but additional messages in the mailbox will not be processed. By default these -messages are sent to the :obj:`deadLetters` of the :obj:`ActorSystem`, but that +messages are sent to the :obj:`deadLetters` of the :obj:`ActorSystem`, but that depends on the mailbox implementation. When stop is called then a call to the ``def postStop`` callback method will @@ -540,11 +540,11 @@ messages on that mailbox, will be there as well. What happens to the actor ------------------------- -If an exception is thrown, the actor instance is discarded and a new instance is +If an exception is thrown, the actor instance is discarded and a new instance is created. This new instance will now be used in the actor references to this actor -(so this is done invisible to the developer). Note that this means that current -state of the failing actor instance is lost if you don't store and restore it in -``preRestart`` and ``postRestart`` callbacks. +(so this is done invisible to the developer). Note that this means that current +state of the failing actor instance is lost if you don't store and restore it in +``preRestart`` and ``postRestart`` callbacks. Extending Actors using PartialFunction chaining diff --git a/akka-docs/scala/code/ActorDocSpec.scala b/akka-docs/scala/code/ActorDocSpec.scala index 744f439c91..57b6ab3bd4 100644 --- a/akka-docs/scala/code/ActorDocSpec.scala +++ b/akka-docs/scala/code/ActorDocSpec.scala @@ -2,6 +2,7 @@ package akka.docs.actor //#imports1 import akka.actor.Actor +import akka.actor.Props import akka.event.Logging //#imports1 @@ -29,12 +30,12 @@ case class Message(s: String) //#context-actorOf class FirstActor extends Actor { - val myActor = context.actorOf[MyActor] + val myActor = context.actorOf(Props[MyActor]) //#context-actorOf //#anonymous-actor def receive = { case m: DoIt ⇒ - context.actorOf(new Actor { + context.actorOf(Props(new Actor { def receive = { case DoIt(msg) ⇒ val replyMsg = doSomeDangerousWork(msg) @@ -42,7 +43,7 @@ class FirstActor extends Actor { self.stop() } def doSomeDangerousWork(msg: ImmutableMessage): String = { "done" } - }) ! m + })) ! m case replyMsg: String ⇒ sender ! replyMsg } @@ -52,7 +53,7 @@ class FirstActor extends Actor { //#system-actorOf object Main extends App { val system = ActorSystem("MySystem") - val myActor = system.actorOf[MyActor] + val myActor = system.actorOf(Props[MyActor]) //#system-actorOf } @@ -94,7 +95,7 @@ class Swapper extends Actor { object SwapperApp extends App { val system = ActorSystem("SwapperSystem") - val swap = system.actorOf[Swapper] + val swap = system.actorOf(Props[Swapper]) swap ! Swap // logs Hi swap ! Swap // logs Ho swap ! Swap // logs Hi @@ -134,20 +135,20 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { //#import-context class FirstActor extends Actor { import context._ - val myActor = actorOf[MyActor] + val myActor = actorOf(Props[MyActor]) def receive = { case x ⇒ myActor ! x } } //#import-context - val first = system.actorOf(new FirstActor) + val first = system.actorOf(Props(new FirstActor)) first.stop() } "creating actor with AkkaSpec.actorOf" in { - val myActor = system.actorOf[MyActor] + val myActor = system.actorOf(Props[MyActor]) // testing the actor @@ -178,7 +179,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { //#creating-constructor // allows passing in arguments to the MyActor constructor - val myActor = system.actorOf(new MyActor("...")) + val myActor = system.actorOf(Props(new MyActor("..."))) //#creating-constructor myActor.stop() @@ -203,7 +204,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { } } - val myActor = system.actorOf(new MyActor) + val myActor = system.actorOf(Props(new MyActor)) implicit val timeout = system.settings.ActorTimeout val future = myActor ? "hello" future.as[String] match { @@ -221,7 +222,7 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { import akka.actor.ReceiveTimeout import akka.util.duration._ class MyActor extends Actor { - context.receiveTimeout = Some(30 seconds) + context.setReceiveTimeout(30 milliseconds) def receive = { case "Hello" ⇒ //... case ReceiveTimeout ⇒ throw new RuntimeException("received timeout") @@ -251,8 +252,6 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { } //#hot-swap-actor - val actor = system.actorOf(new HotSwapActor) - + val actor = system.actorOf(Props(new HotSwapActor)) } - } diff --git a/akka-docs/scala/dispatchers.rst b/akka-docs/scala/dispatchers.rst index c93567e490..51de41316f 100644 --- a/akka-docs/scala/dispatchers.rst +++ b/akka-docs/scala/dispatchers.rst @@ -6,7 +6,7 @@ Dispatchers (Scala) .. sidebar:: Contents .. contents:: :local: - + The Dispatcher is an important piece that allows you to configure the right semantics and parameters for optimal performance, throughput and scalability. Different Actors have different needs. Akka supports dispatchers for both event-driven lightweight threads, allowing creation of millions of threads on a single workstation, and thread-based Actors, where each dispatcher is bound to a dedicated OS thread. @@ -118,7 +118,7 @@ should have, as shown above. This defines the number of messages for a specific Actor the dispatcher should process in one single sweep; in other words, the dispatcher will bunch up to ``throughput`` message invocations together when having elected an actor to run. Setting this to a higher number will increase -throughput but lower fairness, and vice versa. If you don't specify it explicitly +throughput but lower fairness, and vice versa. If you don't specify it explicitly then it uses the value (5) defined for ``default-dispatcher`` in the :ref:`configuration`. Browse the `ScalaDoc `_ or look at the code for all the options available. @@ -135,13 +135,13 @@ Creating a Dispatcher using PriorityGenerator: import akka.dispatch._ import akka.actor._ - + val gen = PriorityGenerator { // Create a new PriorityGenerator, lower prio means more important case 'highpriority => 0 // 'highpriority messages should be treated first if possible case 'lowpriority => 100 // 'lowpriority messages should be treated last if possible case otherwise => 50 // We default to 50 } - + val a = Actor.actorOf( // We create a new Actor that just prints out what it processes Props(new Actor { self ! 'lowpriority diff --git a/akka-docs/scala/routing.rst b/akka-docs/scala/routing.rst index e1a47472aa..b3ee2b2ccd 100644 --- a/akka-docs/scala/routing.rst +++ b/akka-docs/scala/routing.rst @@ -26,8 +26,8 @@ To use it you can either create a Router through the ``routerActor()`` factory m //Two actors, one named Pinger and one named Ponger //The actor(pf) method creates an anonymous actor and starts it - val pinger = actorOf(new Actor { def receive = { case x => println("Pinger: " + x) } }) - val ponger = actorOf(new Actor { def receive = { case x => println("Ponger: " + x) } }) + val pinger = actorOf(Props(new Actor { def receive = { case x => println("Pinger: " + x) } })) + val ponger = actorOf(Props(new Actor { def receive = { case x => println("Ponger: " + x) } })) //A router that dispatches Ping messages to the pinger //and Pong messages to the ponger @@ -53,8 +53,8 @@ Or by mixing in akka.routing.Router: class MyRouter extends Actor with Router { //Our pinger and ponger actors - val pinger = actorOf(new Actor { def receive = { case x => println("Pinger: " + x) } }) - val ponger = actorOf(new Actor { def receive = { case x => println("Ponger: " + x) } }) + val pinger = actorOf(Props(new Actor { def receive = { case x => println("Pinger: " + x) } })) + val ponger = actorOf(Props(new Actor { def receive = { case x => println("Ponger: " + x) } })) //When we get a ping, we dispatch to the pinger //When we get a pong, we dispatch to the ponger def routes = { @@ -64,7 +64,7 @@ Or by mixing in akka.routing.Router: } //Create an instance of our router, and start it - val d = actorOf[MyRouter] + val d = actorOf(Props[MyRouter]) d ! Ping //Prints "Pinger: Ping" d ! Pong //Prints "Ponger: Pong" @@ -90,8 +90,8 @@ Example using the ``loadBalancerActor()`` factory method: //Two actors, one named Pinger and one named Ponger //The actor(pf) method creates an anonymous actor and starts it - val pinger = actorOf(new Actor { def receive = { case x => println("Pinger: " + x) } }) - val ponger = actorOf(new Actor { def receive = { case x => println("Ponger: " + x) } }) + val pinger = actorOf(Props(new Actor { def receive = { case x => println("Pinger: " + x) } })) + val ponger = actorOf(Props(new Actor { def receive = { case x => println("Ponger: " + x) } })) //A load balancer that given a sequence of actors dispatches them accordingly //a CyclicIterator works in a round-robin-fashion @@ -117,14 +117,14 @@ Or by mixing in akka.routing.LoadBalancer //A load balancer that balances between a pinger and a ponger class MyLoadBalancer extends Actor with LoadBalancer { - val pinger = actorOf(new Actor { def receive = { case x => println("Pinger: " + x) } }) - val ponger = actorOf(new Actor { def receive = { case x => println("Ponger: " + x) } }) + val pinger = actorOf(Props(new Actor { def receive = { case x => println("Pinger: " + x) } })) + val ponger = actorOf(Props(new Actor { def receive = { case x => println("Ponger: " + x) } })) val seq = new CyclicIterator[ActorRef](List(pinger,ponger)) } //Create an instance of our loadbalancer, and start it - val d = actorOf[MyLoadBalancer] + val d = actorOf(Props[MyLoadBalancer]) d ! Pong //Prints "Pinger: Pong" d ! Pong //Prints "Ponger: Pong" diff --git a/akka-docs/scala/stm.rst b/akka-docs/scala/stm.rst deleted file mode 100644 index 93aeb15b88..0000000000 --- a/akka-docs/scala/stm.rst +++ /dev/null @@ -1,8 +0,0 @@ - -.. _stm-scala: - -####################################### - Software Transactional Memory (Scala) -####################################### - -Documentation of Akka STM has not been migrated to Akka 2.0-SNAPSHOT yet. \ No newline at end of file diff --git a/akka-docs/scala/testing.rst b/akka-docs/scala/testing.rst index c9a2b5928e..7439a0af8a 100644 --- a/akka-docs/scala/testing.rst +++ b/akka-docs/scala/testing.rst @@ -106,13 +106,13 @@ and in addition allows access to the internal state:: case Ev("back") => goto(1) using "back" } }) - + assert (fsm.stateName == 1) assert (fsm.stateData == "") fsm ! "go" // being a TestActorRef, this runs also on the CallingThreadDispatcher assert (fsm.stateName == 2) assert (fsm.stateData == "go") - + fsm.setState(stateName = 1) assert (fsm.stateName == 1) @@ -235,8 +235,8 @@ common task easy: "An Echo actor" must { "send back messages unchanged" in { - - val echo = Actor.actorOf[EchoActor] + + val echo = Actor.actorOf(Props[EchoActor]) echo ! "hello world" expectMsg("hello world") @@ -352,11 +352,11 @@ with message flows: * :meth:`receiveWhile[T](max: Duration, idle: Duration)(pf: PartialFunction[Any, T]): Seq[T]` Collect messages as long as - + * they are matching the given partial function * the given time interval is not used up * the next message is received within the idle timeout - + All collected messages are returned. The maximum duration defaults to the time remaining in the innermost enclosing :ref:`within ` block and the idle duration defaults to infinity (thereby disabling the @@ -370,7 +370,7 @@ with message flows: :ref:`within ` block. * :meth:`ignoreMsg(pf: PartialFunction[AnyRef, Boolean])` - + :meth:`ignoreNoMsg` The internal :obj:`testActor` contains a partial function for ignoring @@ -431,7 +431,7 @@ maximum time bound, the overall block may take arbitrarily longer in this case. class SomeSpec extends WordSpec with MustMatchers with TestKit { "A Worker" must { "send timely replies" in { - val worker = actorOf(...) + val worker = ActorSystem().actorOf(...) within (500 millis) { worker ! "some work" expectMsg("some result") @@ -471,7 +471,7 @@ simply mix in `ÌmplicitSender`` into your test. class SomeSpec extends WordSpec with MustMatchers with TestKit with ImplicitSender { "A Worker" must { "send timely replies" in { - val worker = actorOf(...) + val worker = ActorSystem().actorOf(...) within (500 millis) { worker ! "some work" // testActor is the "sender" for this message expectMsg("some result") @@ -506,7 +506,7 @@ using a small example:: val probe1 = TestProbe() val probe2 = TestProbe() - val actor = Actor.actorOf[MyDoubleEcho] + val actor = ActorSystem().actorOf(Props[MyDoubleEcho]) actor ! (probe1.ref, probe2.ref) actor ! "hello" probe1.expectMsg(50 millis, "hello") @@ -553,8 +553,9 @@ concerning volume and timing of the message flow while still keeping the network functioning:: val probe = TestProbe() - val source = Actor.actorOf(new Source(probe)) - val dest = Actor.actorOf[Destination] + val system = ActorSystem() + val source = system.actorOf(Props(new Source(probe))) + val dest = system.actorOf(Props[Destination]) source ! "start" probe.expectMsg("work") probe.forward(dest) @@ -613,7 +614,7 @@ or from the client code .. code-block:: scala - val ref = Actor.actorOf(Props[MyActor].withDispatcher(CallingThreadDispatcher.global)) + val ref = system.actorOf(Props[MyActor].withDispatcher(CallingThreadDispatcher.global)) As the :class:`CallingThreadDispatcher` does not have any configurable state, you may always use the (lazily) preallocated one as shown in the examples. @@ -710,7 +711,7 @@ by debuggers as well as logging, where the Akka toolkit offers the following options: * *Logging of exceptions thrown within Actor instances* - + This is always on; in contrast to the other logging mechanisms, this logs at ``ERROR`` level. @@ -723,7 +724,7 @@ options: import akka.event.LoggingReceive def receive = LoggingReceive(this) { case msg => ... - } + } The first argument to :meth:`LoggingReceive` defines the source to be used in the logging events, which should be the current actor. diff --git a/akka-docs/scala/testkit-example.rst b/akka-docs/scala/testkit-example.rst index 5aecba45ab..2290cc84af 100644 --- a/akka-docs/scala/testkit-example.rst +++ b/akka-docs/scala/testkit-example.rst @@ -9,7 +9,7 @@ Ray Roestenburg's example code from `his blog messages = msg :: messages } @@ -95,7 +97,7 @@ Ray Roestenburg's example code from `his blog None } } - + /** * An actor that sends a sequence of messages with a random head list, an interesting value and a random tail list * The idea is that you would like to test that the interesting value is received and that you cant be bothered with the rest diff --git a/akka-docs/scala/transactors.rst b/akka-docs/scala/transactors.rst deleted file mode 100644 index 217b1ecd0c..0000000000 --- a/akka-docs/scala/transactors.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _transactors-scala: - -Transactors (Scala) -=================== - -Documentation of Akka Transactors has not been migrated to Akka 2.0-SNAPSHOT yet. \ No newline at end of file diff --git a/akka-durable-mailboxes/akka-mongo-mailbox/src/main/scala/akka/actor/mailbox/BSONSerialization.scala b/akka-durable-mailboxes/akka-mongo-mailbox/src/main/scala/akka/actor/mailbox/BSONSerialization.scala index 4cfa97bc6b..e6163d80a5 100644 --- a/akka-durable-mailboxes/akka-mongo-mailbox/src/main/scala/akka/actor/mailbox/BSONSerialization.scala +++ b/akka-durable-mailboxes/akka-mongo-mailbox/src/main/scala/akka/actor/mailbox/BSONSerialization.scala @@ -17,7 +17,7 @@ import org.bson.DefaultBSONSerializer import akka.actor.SerializedActorRef import akka.remote.RemoteProtocol.MessageProtocol import akka.remote.MessageSerializer -import akka.actor.{ ActorSystem, ActorSystemImpl } +import akka.actor.{ ActorSystem, ActorSystemImpl, Props } class BSONSerializableMailbox(system: ActorSystem) extends SerializableBSONObject[MongoDurableMessage] with Logging { @@ -71,7 +71,7 @@ class BSONSerializableMailbox(system: ActorSystem) extends SerializableBSONObjec val msg = MessageSerializer.deserialize(system, msgData) val ownerPath = doc.as[String]("ownerPath") val senderPath = doc.as[String]("senderPath") - val sender = systemImpl.actorOf(senderPath) + val sender = systemImpl.actorFor(senderPath) MongoDurableMessage(ownerPath, msg, sender) } diff --git a/akka-durable-mailboxes/akka-mongo-mailbox/src/test/scala/akka/actor/mailbox/MongoBasedMailboxSpec.scala b/akka-durable-mailboxes/akka-mongo-mailbox/src/test/scala/akka/actor/mailbox/MongoBasedMailboxSpec.scala index e1f7529147..ec13cff17f 100644 --- a/akka-durable-mailboxes/akka-mongo-mailbox/src/test/scala/akka/actor/mailbox/MongoBasedMailboxSpec.scala +++ b/akka-durable-mailboxes/akka-mongo-mailbox/src/test/scala/akka/actor/mailbox/MongoBasedMailboxSpec.scala @@ -32,7 +32,7 @@ class MongoBasedMailboxSpec extends DurableMailboxSpec("mongodb", MongoDurableMa } def createMongoMailboxTestActor(id: String)(implicit dispatcher: MessageDispatcher): ActorRef = { - val queueActor = actorOf[MongoMailboxTestActor] + val queueActor = actorOf(Props[MongoMailboxTestActor] queueActor.dispatcher = dispatcher queueActor } @@ -47,7 +47,7 @@ class MongoBasedMailboxSpec extends DurableMailboxSpec("mongodb", MongoDurableMa "should handle reply to ! for 1 message" in { val latch = new CountDownLatch(1) val queueActor = createMongoMailboxTestActor("mongoDB Backend should handle Reply to !") - val sender = actorOf(new Actor { def receive = { case "sum" => latch.countDown } }) + val sender = actorOf(Props(new Actor { def receive = { case "sum" => latch.countDown } }) queueActor.!("sum")(Some(sender)) latch.await(10, TimeUnit.SECONDS) must be (true) diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/GossipMembershipMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/GossipMembershipMultiJvmSpec.scala index 878b7840b0..418f6f385b 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/GossipMembershipMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/GossipMembershipMultiJvmSpec.scala @@ -59,7 +59,7 @@ // remote.start() // barrier("start") -// val actor = system.actorOf[SomeActor]("service-hello") +// val actor = system.actorOf(Props[SomeActor]("service-hello") // actor.isInstanceOf[RoutedActorRef] must be(true) // val connectionCount = NrOfNodes - 1 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/direct_routed/DirectRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/direct_routed/DirectRoutedRemoteActorMultiJvmSpec.scala index e22cfd7195..da6fb8aab0 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/direct_routed/DirectRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/direct_routed/DirectRoutedRemoteActorMultiJvmSpec.scala @@ -47,7 +47,7 @@ class DirectRoutedRemoteActorMultiJvmNode2 extends AkkaRemoteSpec with DefaultTi barrier("start") - val actor = system.actorOf[SomeActor]("service-hello") + val actor = system.actorOf(Props[SomeActor]("service-hello") //actor.isInstanceOf[RoutedActorRef] must be(true) val result = (actor ? "identify").get diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/new_remote_actor/NewRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/new_remote_actor/NewRemoteActorMultiJvmSpec.scala index e42594c949..6d1e3c47cc 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/new_remote_actor/NewRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/new_remote_actor/NewRemoteActorMultiJvmSpec.scala @@ -47,7 +47,7 @@ class NewRemoteActorMultiJvmNode2 extends AkkaRemoteSpec with DefaultTimeout { barrier("start") - val actor = system.actorOf[SomeActor]("service-hello") + val actor = system.actorOf(Props[SomeActor]("service-hello") val result = (actor ? "identify").get result must equal("node1") diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/random_routed/RandomRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/random_routed/RandomRoutedRemoteActorMultiJvmSpec.scala index d985c770c2..860ae3780c 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/random_routed/RandomRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/random_routed/RandomRoutedRemoteActorMultiJvmSpec.scala @@ -71,7 +71,7 @@ class RandomRoutedRemoteActorMultiJvmNode4 extends AkkaRemoteSpec with DefaultTi remote.start() barrier("start") - val actor = system.actorOf[SomeActor]("service-hello") + val actor = system.actorOf(Props[SomeActor]("service-hello") actor.isInstanceOf[RoutedActorRef] must be(true) val connectionCount = NrOfNodes - 1 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/round_robin_routed/RoundRobinRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/round_robin_routed/RoundRobinRoutedRemoteActorMultiJvmSpec.scala index 08c0009f4b..762b26e454 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/round_robin_routed/RoundRobinRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/round_robin_routed/RoundRobinRoutedRemoteActorMultiJvmSpec.scala @@ -71,7 +71,7 @@ class RoundRobinRoutedRemoteActorMultiJvmNode4 extends AkkaRemoteSpec with Defau remote.start() barrier("start") - val actor = system.actorOf[SomeActor]("service-hello") + val actor = system.actorOf(Props[SomeActor]("service-hello") actor.isInstanceOf[RoutedActorRef] must be(true) val connectionCount = NrOfNodes - 1 diff --git a/akka-remote/src/multi-jvm/scala/akka/remote/scatter_gather_routed/ScatterGatherRoutedRemoteActorMultiJvmSpec.scala b/akka-remote/src/multi-jvm/scala/akka/remote/scatter_gather_routed/ScatterGatherRoutedRemoteActorMultiJvmSpec.scala index 764cda813e..fb511b88b5 100644 --- a/akka-remote/src/multi-jvm/scala/akka/remote/scatter_gather_routed/ScatterGatherRoutedRemoteActorMultiJvmSpec.scala +++ b/akka-remote/src/multi-jvm/scala/akka/remote/scatter_gather_routed/ScatterGatherRoutedRemoteActorMultiJvmSpec.scala @@ -71,7 +71,7 @@ class ScatterGatherRoutedRemoteActorMultiJvmNode4 extends AkkaRemoteSpec with De remote.start() barrier("start") - val actor = system.actorOf[SomeActor]("service-hello") + val actor = system.actorOf(Props[SomeActor]("service-hello") actor.isInstanceOf[RoutedActorRef] must be(true) actor.asInstanceOf[RoutedActorRef].router.isInstanceOf[ScatterGatherFirstCompletedRouter] must be(true) diff --git a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala index 86378569b3..b82699ebe4 100644 --- a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala +++ b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala @@ -6,7 +6,7 @@ package sample.fsm.dining.become //Akka adaptation of //http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/ -import akka.actor.{ ActorRef, Actor, ActorSystem } +import akka.actor._ import akka.util.duration._ /* @@ -137,12 +137,12 @@ object DiningHakkers { def run { //Create 5 chopsticks - val chopsticks = for (i ← 1 to 5) yield system.actorOf[Chopstick]("Chopstick " + i) + val chopsticks = for (i ← 1 to 5) yield system.actorOf(Props[Chopstick], "Chopstick " + i) //Create 5 awesome hakkers and assign them their left and right chopstick val hakkers = for { (name, i) ← List("Ghosh", "Bonér", "Klang", "Krasser", "Manie").zipWithIndex - } yield system.actorOf(new Hakker(name, chopsticks(i), chopsticks((i + 1) % 5))) + } yield system.actorOf(Props(new Hakker(name, chopsticks(i), chopsticks((i + 1) % 5)))) //Signal all hakkers that they should start thinking, and watch the show hakkers.foreach(_ ! Think) diff --git a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala index ddb000f5c4..52ed49797a 100644 --- a/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala +++ b/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnFsm.scala @@ -3,7 +3,7 @@ */ package sample.fsm.dining.fsm -import akka.actor.{ ActorRef, Actor, FSM, ActorSystem } +import akka.actor._ import akka.actor.FSM._ import akka.util.Duration import akka.util.duration._ @@ -175,11 +175,11 @@ object DiningHakkersOnFsm { def run = { // Create 5 chopsticks - val chopsticks = for (i ← 1 to 5) yield system.actorOf[Chopstick]("Chopstick " + i) + val chopsticks = for (i ← 1 to 5) yield system.actorOf(Props[Chopstick], "Chopstick " + i) // Create 5 awesome fsm hakkers and assign them their left and right chopstick val hakkers = for { (name, i) ← List("Ghosh", "Bonér", "Klang", "Krasser", "Manie").zipWithIndex - } yield system.actorOf(new FSMHakker(name, chopsticks(i), chopsticks((i + 1) % 5))) + } yield system.actorOf(Props(new FSMHakker(name, chopsticks(i), chopsticks((i + 1) % 5)))) hakkers.foreach(_ ! Think) } diff --git a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala index 65f530c077..710a099312 100644 --- a/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala +++ b/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala @@ -3,19 +3,19 @@ */ package sample.hello -import akka.actor.{ ActorSystem, Actor } +import akka.actor.{ ActorSystem, Actor, Props } case object Start object Main { def main(args: Array[String]): Unit = { val system = ActorSystem() - system.actorOf[HelloActor] ! Start + system.actorOf(Props[HelloActor]) ! Start } } class HelloActor extends Actor { - val worldActor = context.actorOf[WorldActor] + val worldActor = context.actorOf(Props[WorldActor]) def receive = { case Start ⇒ worldActor ! "Hello" case s: String ⇒ diff --git a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala index ecbfcb315c..20db50f487 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala @@ -94,7 +94,7 @@ object TestActorRef { "Could not instantiate Actor" + "\nMake sure Actor is NOT defined inside a class/trait," + "\nif so put it outside the class/trait, f.e. in a companion object," + - "\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'.", exception) + "\nOR try to change: 'actorOf(Props[MyActor]' to 'actorOf(Props(new MyActor)'.", exception) } }), name) } diff --git a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala index b524114046..d295757f85 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestKit.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestKit.scala @@ -54,7 +54,7 @@ class TestActor(queue: BlockingDeque[TestActor.Message]) extends Actor { * *
  * class Test extends TestKit {
- *     val test = actorOf[SomeActor]
+ *     val test = actorOf(Props[SomeActor]
  *
  *     within (1 second) {
  *       test ! SomeWork
diff --git a/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java b/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java
index d4d75c34b4..52786abc36 100644
--- a/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java
+++ b/akka-tutorials/akka-tutorial-first/src/main/java/akka/tutorial/first/java/Pi.java
@@ -4,6 +4,7 @@
 
 package akka.tutorial.first.java;
 
+import akka.actor.Props;
 import akka.actor.ActorRef;
 import akka.actor.ActorSystem;
 import akka.actor.InternalActorRef;
@@ -112,7 +113,7 @@ public class Pi {
             };
             LinkedList actors = new LinkedList() {
                 {
-                    for (int i = 0; i < nrOfWorkers; i++) add(getContext().actorOf(Worker.class));
+                    for (int i = 0; i < nrOfWorkers; i++) add(getContext().actorOf(new Props(Worker.class)));
                 }
             };
                         // FIXME routers are intended to be used like this
@@ -166,11 +167,11 @@ public class Pi {
         final CountDownLatch latch = new CountDownLatch(1);
 
         // create the master
-        ActorRef master = system.actorOf(new UntypedActorFactory() {
+        ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
             public UntypedActor create() {
                 return new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch);
             }
-        });
+        }));
 
         // start the calculation
         master.tell(new Calculate());
diff --git a/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala b/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala
index f0c7b9bb2d..1c09ee4838 100644
--- a/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala
+++ b/akka-tutorials/akka-tutorial-first/src/main/scala/Pi.scala
@@ -5,8 +5,7 @@ package akka.tutorial.first.scala
 
 import java.util.concurrent.CountDownLatch
 import akka.routing.{ RoutedActorRef, LocalConnectionManager, RoundRobinRouter, RoutedProps }
-import akka.actor.{ ActorSystemImpl, Actor, ActorSystem }
-import akka.actor.InternalActorRef
+import akka.actor._
 
 object Pi extends App {
 
@@ -53,7 +52,7 @@ object Pi extends App {
     var start: Long = _
 
     // create the workers
-    val workers = Vector.fill(nrOfWorkers)(context.actorOf[Worker])
+    val workers = Vector.fill(nrOfWorkers)(context.actorOf(Props[Worker]))
 
     // wrap them with a load-balancing router
     // FIXME routers are intended to be used like this
@@ -99,7 +98,7 @@ object Pi extends App {
     val latch = new CountDownLatch(1)
 
     // create the master
-    val master = system.actorOf(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch))
+    val master = system.actorOf(Props(new Master(nrOfWorkers, nrOfMessages, nrOfElements, latch)))
 
     // start the calculation
     master ! Calculate